better_record 0.7.5 → 0.8.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/app/models/better_record/current.rb +2 -0
 - data/config/initializers/core_ext/integer.rb +38 -0
 - data/config/initializers/core_ext/string.rb +11 -0
 - data/config/initializers/inflections.rb +2 -0
 - data/config/routes.rb +7 -1
 - data/lib/better_record.rb +36 -8
 - data/lib/better_record/concerns/controllers/authenticatable.rb +30 -0
 - data/lib/better_record/concerns/controllers/sessionable.rb +33 -0
 - data/lib/better_record/concerns/controllers/uploadable.rb +66 -0
 - data/lib/better_record/encoder.rb +46 -0
 - data/lib/better_record/jwt.rb +127 -0
 - data/lib/better_record/rspec/expectations.rb +3 -0
 - data/lib/better_record/rspec/expectations/write.rb +75 -0
 - data/lib/better_record/version.rb +1 -1
 - data/lib/generators/better_record/setup/setup_generator.rb +27 -18
 - data/lib/generators/better_record/setup/templates/initializer.rb +47 -10
 - metadata +71 -3
 
    
        checksums.yaml
    CHANGED
    
    | 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            ---
         
     | 
| 
       2 
2 
     | 
    
         
             
            SHA256:
         
     | 
| 
       3 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       4 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 3 
     | 
    
         
            +
              metadata.gz: 15065e4dbf375d7777148aa24e0a36afde1c7db1ddb458c133fb38cac4b8cb7e
         
     | 
| 
      
 4 
     | 
    
         
            +
              data.tar.gz: af39d1a5bf2bfeb0d16feb26bca64f2d6d2ddd0006d63317d764eb163e650c45
         
     | 
| 
       5 
5 
     | 
    
         
             
            SHA512:
         
     | 
| 
       6 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       7 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 6 
     | 
    
         
            +
              metadata.gz: 20f71fc1960ba2478f065cd8d9d67b3c8cc9123e000c7c4648b7e77c5fccc54e54226e131bf63fb42a6096e7476571c6e73c2c7d307ccc625580b412a3d722ee
         
     | 
| 
      
 7 
     | 
    
         
            +
              data.tar.gz: fd5479dce949e8e0cc5934319244dc4abac74a5945f7e29d1faa751afc1bd14400123fcc307051b8879c999be84eb535317820604871bbabbf3661af2aa20226
         
     | 
| 
         @@ -1,5 +1,43 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            class Integer
         
     | 
| 
      
 2 
     | 
    
         
            +
              def self.models
         
     | 
| 
      
 3 
     | 
    
         
            +
                @@record_models ||= Hash[*Dir[Rails.root.join('app', 'models', '**.rb')].map do |file|
         
     | 
| 
      
 4 
     | 
    
         
            +
                  @str_idx ||= Rails.root.join('app', 'models').to_s.size + 1
         
     | 
| 
      
 5 
     | 
    
         
            +
                  str = file[@str_idx..-4]
         
     | 
| 
      
 6 
     | 
    
         
            +
                  [str, str]
         
     | 
| 
      
 7 
     | 
    
         
            +
                end.flatten]
         
     | 
| 
      
 8 
     | 
    
         
            +
              end
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
              def self.add_lookup_method(method_name, klass)
         
     | 
| 
      
 11 
     | 
    
         
            +
                self.__send__ :define_method, method_name.to_sym do
         
     | 
| 
      
 12 
     | 
    
         
            +
                  klass.find_by(id: self)
         
     | 
| 
      
 13 
     | 
    
         
            +
                end
         
     | 
| 
      
 14 
     | 
    
         
            +
              end
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
       2 
16 
     | 
    
         
             
              def cents
         
     | 
| 
       3 
17 
     | 
    
         
             
                StoreAsInt.money(self)
         
     | 
| 
       4 
18 
     | 
    
         
             
              end
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
              def percentage
         
     | 
| 
      
 21 
     | 
    
         
            +
                StoreAsInt.exchange_rate(self)
         
     | 
| 
      
 22 
     | 
    
         
            +
              end
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
              def method_missing(method, *args)
         
     | 
| 
      
 25 
     | 
    
         
            +
                begin
         
     | 
| 
      
 26 
     | 
    
         
            +
                  if m = is_model_lookup?(method)
         
     | 
| 
      
 27 
     | 
    
         
            +
                    m = m.classify.constantize
         
     | 
| 
      
 28 
     | 
    
         
            +
                    Integer.add_lookup_method method, m
         
     | 
| 
      
 29 
     | 
    
         
            +
                    m.find_by(id: self)
         
     | 
| 
      
 30 
     | 
    
         
            +
                  else
         
     | 
| 
      
 31 
     | 
    
         
            +
                    raise NoMethodError
         
     | 
| 
      
 32 
     | 
    
         
            +
                  end
         
     | 
| 
      
 33 
     | 
    
         
            +
                rescue NoMethodError
         
     | 
| 
      
 34 
     | 
    
         
            +
                  super(method, *args)
         
     | 
| 
      
 35 
     | 
    
         
            +
                end
         
     | 
| 
      
 36 
     | 
    
         
            +
              end
         
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
      
 38 
     | 
    
         
            +
              private
         
     | 
| 
      
 39 
     | 
    
         
            +
                def is_model_lookup?(method = nil)
         
     | 
| 
      
 40 
     | 
    
         
            +
                  (method.to_s =~ /^to\_[a-zA-Z\_0-9]+$/) &&
         
     | 
| 
      
 41 
     | 
    
         
            +
                  (Integer.models[method.to_s.sub("to_", '')])
         
     | 
| 
      
 42 
     | 
    
         
            +
                end
         
     | 
| 
       5 
43 
     | 
    
         
             
            end
         
     | 
    
        data/config/routes.rb
    CHANGED
    
    | 
         @@ -1,4 +1,10 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            BetterRecord::Engine.routes.draw do
         
     | 
| 
       2 
2 
     | 
    
         
             
              root to: 'table_sizes#index'
         
     | 
| 
       3 
     | 
    
         
            -
             
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
              resources :table_sizes, only: %i[ index show ]
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
              namespace :api do
         
     | 
| 
      
 7 
     | 
    
         
            +
                resources :sessions, only: %i[ new create destroy ]
         
     | 
| 
      
 8 
     | 
    
         
            +
                get :sessions, to: 'sessions#new'
         
     | 
| 
      
 9 
     | 
    
         
            +
              end
         
     | 
| 
       4 
10 
     | 
    
         
             
            end
         
     | 
    
        data/lib/better_record.rb
    CHANGED
    
    | 
         @@ -1,25 +1,53 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            require  
     | 
| 
       2 
     | 
    
         
            -
            require  
     | 
| 
      
 1 
     | 
    
         
            +
            require 'active_support'
         
     | 
| 
      
 2 
     | 
    
         
            +
            require 'active_record'
         
     | 
| 
      
 3 
     | 
    
         
            +
            require 'csv'
         
     | 
| 
       3 
4 
     | 
    
         | 
| 
       4 
5 
     | 
    
         
             
            Dir.glob("#{File.expand_path(__dir__)}/core_ext/*.rb").each do |d|
         
     | 
| 
       5 
6 
     | 
    
         
             
              require d
         
     | 
| 
       6 
7 
     | 
    
         
             
            end
         
     | 
| 
       7 
8 
     | 
    
         | 
| 
       8 
9 
     | 
    
         
             
            module BetterRecord
         
     | 
| 
      
 10 
     | 
    
         
            +
              ATTRIBUTE_METHODS = [
         
     | 
| 
      
 11 
     | 
    
         
            +
                :default_polymorphic_method,
         
     | 
| 
      
 12 
     | 
    
         
            +
                :db_audit_schema,
         
     | 
| 
      
 13 
     | 
    
         
            +
                :has_auditing_relation_by_default,
         
     | 
| 
      
 14 
     | 
    
         
            +
                :audit_relation_name,
         
     | 
| 
      
 15 
     | 
    
         
            +
                :layout_template,
         
     | 
| 
      
 16 
     | 
    
         
            +
                :app_domain_name,
         
     | 
| 
      
 17 
     | 
    
         
            +
                :after_login_path,
         
     | 
| 
      
 18 
     | 
    
         
            +
                :session_class,
         
     | 
| 
      
 19 
     | 
    
         
            +
                :session_column,
         
     | 
| 
      
 20 
     | 
    
         
            +
                :session_data,
         
     | 
| 
      
 21 
     | 
    
         
            +
                :session_authenticate_method,
         
     | 
| 
      
 22 
     | 
    
         
            +
                :certificate_session_class,
         
     | 
| 
      
 23 
     | 
    
         
            +
                :certificate_session_column,
         
     | 
| 
      
 24 
     | 
    
         
            +
                :certificate_session_user_method,
         
     | 
| 
      
 25 
     | 
    
         
            +
              ].freeze
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
       9 
27 
     | 
    
         
             
              class << self
         
     | 
| 
       10 
     | 
    
         
            -
                 
     | 
| 
       11 
     | 
    
         
            -
             
     | 
| 
       12 
     | 
    
         
            -
             
     | 
| 
       13 
     | 
    
         
            -
             
     | 
| 
       14 
     | 
    
         
            -
             
     | 
| 
       15 
     | 
    
         
            -
             
     | 
| 
      
 28 
     | 
    
         
            +
                def attributes
         
     | 
| 
      
 29 
     | 
    
         
            +
                  attrs_hash.dup
         
     | 
| 
      
 30 
     | 
    
         
            +
                end
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
                attr_accessor *ATTRIBUTE_METHODS
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
      
 34 
     | 
    
         
            +
                private
         
     | 
| 
      
 35 
     | 
    
         
            +
                  def attrs_hash
         
     | 
| 
      
 36 
     | 
    
         
            +
                    @attrs ||= ATTRIBUTE_METHODS.map {|k| [k, true]}.to_h.with_indifferent_access.freeze
         
     | 
| 
      
 37 
     | 
    
         
            +
                  end
         
     | 
| 
       16 
38 
     | 
    
         
             
              end
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
       17 
40 
     | 
    
         
             
              self.default_polymorphic_method = (ENV.fetch('BR_DEFAULT_POLYMORPHIC_METHOD') { :polymorphic_name }).to_sym
         
     | 
| 
       18 
41 
     | 
    
         
             
              self.db_audit_schema = ENV.fetch('BR_DB_AUDIT_SCHEMA') { 'auditing' }
         
     | 
| 
       19 
42 
     | 
    
         
             
              self.has_auditing_relation_by_default = ActiveRecord::Type::Boolean.new.cast(ENV.fetch('BR_ADD_HAS_MANY') { true })
         
     | 
| 
       20 
43 
     | 
    
         
             
              self.audit_relation_name = (ENV.fetch('BR_AUDIT_RELATION_NAME') { 'logged_actions' }).to_sym
         
     | 
| 
       21 
44 
     | 
    
         
             
              self.layout_template = (ENV.fetch('BR_LAYOUT_TEMPLATE') { 'better_record/layout' }).to_s
         
     | 
| 
       22 
45 
     | 
    
         
             
              self.app_domain_name = (ENV.fetch('APP_DOMAIN_NAME') { 'non_existant_domain.com' }).to_s
         
     | 
| 
      
 46 
     | 
    
         
            +
              self.after_login_path = (ENV.fetch('BR_AFTER_LOGIN_PATH') { nil })
         
     | 
| 
      
 47 
     | 
    
         
            +
              self.session_column = (ENV.fetch('BR_SESSION_COLUMN') { :id }).to_sym
         
     | 
| 
      
 48 
     | 
    
         
            +
              self.session_authenticate_method = (ENV.fetch('BR_SESSION_AUTHENTICATE_METHOD') { :authenticate }).to_sym
         
     | 
| 
      
 49 
     | 
    
         
            +
              self.certificate_session_column = (ENV.fetch('BR_CERTIFICATE_SESSION_COLUMN') { :certificate }).to_sym
         
     | 
| 
      
 50 
     | 
    
         
            +
              self.certificate_session_user_method = (ENV.fetch('BR_CERTIFICATE_SESSION_USER_METHOD') { :user }).to_sym
         
     | 
| 
       23 
51 
     | 
    
         
             
            end
         
     | 
| 
       24 
52 
     | 
    
         | 
| 
       25 
53 
     | 
    
         
             
            Dir.glob("#{File.expand_path(__dir__)}/better_record/*.rb").each do |d|
         
     | 
| 
         @@ -0,0 +1,30 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'active_support/concern'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module BetterRecord
         
     | 
| 
      
 4 
     | 
    
         
            +
              module Authenticatable
         
     | 
| 
      
 5 
     | 
    
         
            +
                extend ActiveSupport::Concern
         
     | 
| 
      
 6 
     | 
    
         
            +
                include BetterRecord::JWT::ControllerMethods
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
                included do
         
     | 
| 
      
 9 
     | 
    
         
            +
                  before_action :check_user
         
     | 
| 
      
 10 
     | 
    
         
            +
                end
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
                def method_missing(method, *args)
         
     | 
| 
      
 13 
     | 
    
         
            +
                  begin
         
     | 
| 
      
 14 
     | 
    
         
            +
                    if BetterRecord.attributes[method.to_sym]
         
     | 
| 
      
 15 
     | 
    
         
            +
                      m = method.to_sym
         
     | 
| 
      
 16 
     | 
    
         
            +
                      self.class.define_method m do
         
     | 
| 
      
 17 
     | 
    
         
            +
                        BetterRecord.__send__ m
         
     | 
| 
      
 18 
     | 
    
         
            +
                      end
         
     | 
| 
      
 19 
     | 
    
         
            +
                      BetterRecord.__send__ m
         
     | 
| 
      
 20 
     | 
    
         
            +
                    else
         
     | 
| 
      
 21 
     | 
    
         
            +
                      raise NoMethodError
         
     | 
| 
      
 22 
     | 
    
         
            +
                    end
         
     | 
| 
      
 23 
     | 
    
         
            +
                  rescue NoMethodError
         
     | 
| 
      
 24 
     | 
    
         
            +
                    super(method, *args)
         
     | 
| 
      
 25 
     | 
    
         
            +
                  end
         
     | 
| 
      
 26 
     | 
    
         
            +
                end
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
              end
         
     | 
| 
      
 30 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,33 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'active_support/concern'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module BetterRecord
         
     | 
| 
      
 4 
     | 
    
         
            +
              module Sessionable
         
     | 
| 
      
 5 
     | 
    
         
            +
                extend ActiveSupport::Concern
         
     | 
| 
      
 6 
     | 
    
         
            +
                include BetterRecord::JWT::ControllerMethods
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
                included do
         
     | 
| 
      
 9 
     | 
    
         
            +
                  skip_before_action :check_user, raise: false
         
     | 
| 
      
 10 
     | 
    
         
            +
                end
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
                def new
         
     | 
| 
      
 13 
     | 
    
         
            +
                  session[:referrer] ||= request.referrer
         
     | 
| 
      
 14 
     | 
    
         
            +
                  p session[:referrer], request.referrer
         
     | 
| 
      
 15 
     | 
    
         
            +
                  if (header_hash = request.headers.to_h.deep_symbolize_keys)[:HTTP_X_SSL_CERT].present?
         
     | 
| 
      
 16 
     | 
    
         
            +
                    create_session_from_certificate(header_hash[:HTTP_X_SSL_CERT])
         
     | 
| 
      
 17 
     | 
    
         
            +
                    redirect_to (session.delete(:referrer) || __send__(after_login_path) || root_path)
         
     | 
| 
      
 18 
     | 
    
         
            +
                  end
         
     | 
| 
      
 19 
     | 
    
         
            +
                end
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
                def create
         
     | 
| 
      
 22 
     | 
    
         
            +
                  if(user = session_class.__send__(session_authenticate_method, params))
         
     | 
| 
      
 23 
     | 
    
         
            +
                    session[:better_record] = create_jwt(user)
         
     | 
| 
      
 24 
     | 
    
         
            +
                  end
         
     | 
| 
      
 25 
     | 
    
         
            +
                  respond_to do |format|
         
     | 
| 
      
 26 
     | 
    
         
            +
                    format.json
         
     | 
| 
      
 27 
     | 
    
         
            +
                    format.html do
         
     | 
| 
      
 28 
     | 
    
         
            +
                      return redirect_to (session.delete(:referrer) || __send__(after_login_path) || root_path)
         
     | 
| 
      
 29 
     | 
    
         
            +
                    end
         
     | 
| 
      
 30 
     | 
    
         
            +
                  end
         
     | 
| 
      
 31 
     | 
    
         
            +
                end
         
     | 
| 
      
 32 
     | 
    
         
            +
              end
         
     | 
| 
      
 33 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,66 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module Uploadable
         
     | 
| 
      
 2 
     | 
    
         
            +
              extend ActiveSupport::Concern
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
              def whitelisted_upload_params
         
     | 
| 
      
 5 
     | 
    
         
            +
                params.require(:upload).permit(:file, :staff_id)
         
     | 
| 
      
 6 
     | 
    
         
            +
              end
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
              def csv_upload(job, whitelisted_params, upload_key, prefix, job_sym = :staff_id, redirecting = false)
         
     | 
| 
      
 9 
     | 
    
         
            +
                p whitelisted_params
         
     | 
| 
      
 10 
     | 
    
         
            +
                uploaded = whitelisted_params[upload_key]
         
     | 
| 
      
 11 
     | 
    
         
            +
                job_id = whitelisted_params[job_sym]
         
     | 
| 
      
 12 
     | 
    
         
            +
                @file_stats = {
         
     | 
| 
      
 13 
     | 
    
         
            +
                  name: uploaded.original_filename,
         
     | 
| 
      
 14 
     | 
    
         
            +
                  "mime-type" => uploaded.content_type,
         
     | 
| 
      
 15 
     | 
    
         
            +
                  size: view_context.number_to_human_size(uploaded.size)
         
     | 
| 
      
 16 
     | 
    
         
            +
                }
         
     | 
| 
      
 17 
     | 
    
         
            +
                if verify_file(whitelisted_params, upload_key)
         
     | 
| 
      
 18 
     | 
    
         
            +
                  File.open(Rails.root.join('public', 'import_csv', "#{prefix}_#{Time.now.to_i}#{rand(1000..100000)}.csv"), 'wb') do |file|
         
     | 
| 
      
 19 
     | 
    
         
            +
                    uploaded = BetterRecord::Encoder.new(uploaded.read).to_utf8
         
     | 
| 
      
 20 
     | 
    
         
            +
                    file.write(uploaded)
         
     | 
| 
      
 21 
     | 
    
         
            +
                    job.perform_later file.path, job_id, @file_stats[:name]
         
     | 
| 
      
 22 
     | 
    
         
            +
                  end
         
     | 
| 
      
 23 
     | 
    
         
            +
                  if redirecting
         
     | 
| 
      
 24 
     | 
    
         
            +
                    flash[:success] ||= []
         
     | 
| 
      
 25 
     | 
    
         
            +
                    flash[:success] << 'File Uploaded'
         
     | 
| 
      
 26 
     | 
    
         
            +
                  else
         
     | 
| 
      
 27 
     | 
    
         
            +
                    flash.now[:success] ||= []
         
     | 
| 
      
 28 
     | 
    
         
            +
                    flash.now[:success] << 'File Uploaded'
         
     | 
| 
      
 29 
     | 
    
         
            +
                  end
         
     | 
| 
      
 30 
     | 
    
         
            +
                  return true
         
     | 
| 
      
 31 
     | 
    
         
            +
                else
         
     | 
| 
      
 32 
     | 
    
         
            +
                  msg = [
         
     | 
| 
      
 33 
     | 
    
         
            +
                    'something went wrong',
         
     | 
| 
      
 34 
     | 
    
         
            +
                    'Only csv files with the correct headers are supported',
         
     | 
| 
      
 35 
     | 
    
         
            +
                    "content type: #{whitelisted_params[upload_key].content_type}", "file name: #{whitelisted_params[upload_key].original_filename}"
         
     | 
| 
      
 36 
     | 
    
         
            +
                  ]
         
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
      
 38 
     | 
    
         
            +
                  if redirecting
         
     | 
| 
      
 39 
     | 
    
         
            +
                    flash[:danger] = msg
         
     | 
| 
      
 40 
     | 
    
         
            +
                  else
         
     | 
| 
      
 41 
     | 
    
         
            +
                    flash.now[:danger] = msg
         
     | 
| 
      
 42 
     | 
    
         
            +
             
     | 
| 
      
 43 
     | 
    
         
            +
                    render :show
         
     | 
| 
      
 44 
     | 
    
         
            +
                  end
         
     | 
| 
      
 45 
     | 
    
         
            +
                end
         
     | 
| 
      
 46 
     | 
    
         
            +
              end
         
     | 
| 
      
 47 
     | 
    
         
            +
             
     | 
| 
      
 48 
     | 
    
         
            +
              private
         
     | 
| 
      
 49 
     | 
    
         
            +
                def verify_file(whitelisted_params, upload_key)
         
     | 
| 
      
 50 
     | 
    
         
            +
                  correct_mime_type(whitelisted_params, upload_key) && /\.csv/ =~ whitelisted_params[upload_key].original_filename
         
     | 
| 
      
 51 
     | 
    
         
            +
                end
         
     | 
| 
      
 52 
     | 
    
         
            +
             
     | 
| 
      
 53 
     | 
    
         
            +
                def correct_mime_type(whitelisted_params, upload_key)
         
     | 
| 
      
 54 
     | 
    
         
            +
                  [
         
     | 
| 
      
 55 
     | 
    
         
            +
                    "text/csv",
         
     | 
| 
      
 56 
     | 
    
         
            +
                    "text/plain",
         
     | 
| 
      
 57 
     | 
    
         
            +
                    "application/vnd.ms-excel",
         
     | 
| 
      
 58 
     | 
    
         
            +
                    "text/x-csv",
         
     | 
| 
      
 59 
     | 
    
         
            +
                    "application/csv",
         
     | 
| 
      
 60 
     | 
    
         
            +
                    "application/x-csv",
         
     | 
| 
      
 61 
     | 
    
         
            +
                    "text/csv",
         
     | 
| 
      
 62 
     | 
    
         
            +
                    "text/comma-separated-values",
         
     | 
| 
      
 63 
     | 
    
         
            +
                    "text/x-comma-separated-values"
         
     | 
| 
      
 64 
     | 
    
         
            +
                  ].any? {|mime| mime == whitelisted_params[upload_key].content_type}
         
     | 
| 
      
 65 
     | 
    
         
            +
                end
         
     | 
| 
      
 66 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,46 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module BetterRecord
         
     | 
| 
      
 2 
     | 
    
         
            +
              class Encoder
         
     | 
| 
      
 3 
     | 
    
         
            +
                def initialize(str)
         
     | 
| 
      
 4 
     | 
    
         
            +
                  @str = str
         
     | 
| 
      
 5 
     | 
    
         
            +
                end
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
                def to_utf8
         
     | 
| 
      
 8 
     | 
    
         
            +
                  return @str if is_utf8?
         
     | 
| 
      
 9 
     | 
    
         
            +
                  encoding = find_encoding
         
     | 
| 
      
 10 
     | 
    
         
            +
                  @str.force_encoding(encoding).encode('utf-8', invalid: :replace, undef: :replace)
         
     | 
| 
      
 11 
     | 
    
         
            +
                end
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
                def find_encoding
         
     | 
| 
      
 14 
     | 
    
         
            +
                  puts 'utf-8' if is_utf8?
         
     | 
| 
      
 15 
     | 
    
         
            +
                  return 'utf-8' if is_utf8?
         
     | 
| 
      
 16 
     | 
    
         
            +
                  puts 'iso-8859-1' if is_iso8859?
         
     | 
| 
      
 17 
     | 
    
         
            +
                  return 'iso-8859-1' if is_iso8859?
         
     | 
| 
      
 18 
     | 
    
         
            +
                  puts 'Windows-1252' if is_windows?
         
     | 
| 
      
 19 
     | 
    
         
            +
                  return 'Windows-1252' if is_windows?
         
     | 
| 
      
 20 
     | 
    
         
            +
                  raise ArgumentError.new "Invalid Encoding"
         
     | 
| 
      
 21 
     | 
    
         
            +
                end
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
                def is_utf8?
         
     | 
| 
      
 24 
     | 
    
         
            +
                  is_encoding?(Encoding::UTF_8)
         
     | 
| 
      
 25 
     | 
    
         
            +
                end
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
                def is_iso8859?
         
     | 
| 
      
 28 
     | 
    
         
            +
                  is_encoding?(Encoding::ISO_8859_1)
         
     | 
| 
      
 29 
     | 
    
         
            +
                end
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
                def is_windows?(str)
         
     | 
| 
      
 32 
     | 
    
         
            +
                  is_encoding?(Encoding::Windows_1252)
         
     | 
| 
      
 33 
     | 
    
         
            +
                end
         
     | 
| 
      
 34 
     | 
    
         
            +
             
     | 
| 
      
 35 
     | 
    
         
            +
                def is_encoding?(encoding_check)
         
     | 
| 
      
 36 
     | 
    
         
            +
                  case @str.encoding
         
     | 
| 
      
 37 
     | 
    
         
            +
                  when encoding_check
         
     | 
| 
      
 38 
     | 
    
         
            +
                    @str.valid_encoding?
         
     | 
| 
      
 39 
     | 
    
         
            +
                  when Encoding::ASCII_8BIT, Encoding::US_ASCII
         
     | 
| 
      
 40 
     | 
    
         
            +
                    @str.dup.force_encoding(encoding_check).valid_encoding?
         
     | 
| 
      
 41 
     | 
    
         
            +
                  else
         
     | 
| 
      
 42 
     | 
    
         
            +
                    false
         
     | 
| 
      
 43 
     | 
    
         
            +
                  end
         
     | 
| 
      
 44 
     | 
    
         
            +
                end
         
     | 
| 
      
 45 
     | 
    
         
            +
              end
         
     | 
| 
      
 46 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,127 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'jwt'
         
     | 
| 
      
 2 
     | 
    
         
            +
            require 'jwe'
         
     | 
| 
      
 3 
     | 
    
         
            +
            require 'openssl'
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            module BetterRecord
         
     | 
| 
      
 6 
     | 
    
         
            +
              class JWT
         
     | 
| 
      
 7 
     | 
    
         
            +
                CHARACTERS = [*('a'..'z'), *('A'..'Z'), *(0..9).map(&:to_s), *'!@#$%^&*()'.split('')]
         
     | 
| 
      
 8 
     | 
    
         
            +
                DEFAULT_OPTIONS = { enc:  'A256GCM', alg: 'dir', zip: 'DEF' }
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
                class << self
         
     | 
| 
      
 11 
     | 
    
         
            +
                  def gen_encryption_key
         
     | 
| 
      
 12 
     | 
    
         
            +
                    SecureRandom.random_bytes(32)
         
     | 
| 
      
 13 
     | 
    
         
            +
                  end
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
                  def encryption_key
         
     | 
| 
      
 16 
     | 
    
         
            +
                    @encryption_key ||= gen_encryption_key
         
     | 
| 
      
 17 
     | 
    
         
            +
                  end
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
                  def encryption_key=(key)
         
     | 
| 
      
 20 
     | 
    
         
            +
                    @encryption_key = key || gen_encryption_key
         
     | 
| 
      
 21 
     | 
    
         
            +
                  end
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
                  def gen_signing_key(length = 50)
         
     | 
| 
      
 24 
     | 
    
         
            +
                    (0...length).map { CHARACTERS[rand(CHARACTERS.length)] }.join
         
     | 
| 
      
 25 
     | 
    
         
            +
                  end
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
                  def signing_key
         
     | 
| 
      
 28 
     | 
    
         
            +
                    @signing_key ||= gen_signing_key
         
     | 
| 
      
 29 
     | 
    
         
            +
                  end
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
                  def signing_key=(key)
         
     | 
| 
      
 32 
     | 
    
         
            +
                    @signing_key = key || gen_signing_key
         
     | 
| 
      
 33 
     | 
    
         
            +
                  end
         
     | 
| 
      
 34 
     | 
    
         
            +
             
     | 
| 
      
 35 
     | 
    
         
            +
                  def encrypt_options
         
     | 
| 
      
 36 
     | 
    
         
            +
                    @encrypt_options ||= DEFAULT_OPTIONS
         
     | 
| 
      
 37 
     | 
    
         
            +
                  end
         
     | 
| 
      
 38 
     | 
    
         
            +
             
     | 
| 
      
 39 
     | 
    
         
            +
                  def encrypt_options=(options)
         
     | 
| 
      
 40 
     | 
    
         
            +
                    @encrypt_options = options || DEFAULT_OPTIONS
         
     | 
| 
      
 41 
     | 
    
         
            +
                  end
         
     | 
| 
      
 42 
     | 
    
         
            +
             
     | 
| 
      
 43 
     | 
    
         
            +
                  def encode(payload, sig_key = nil, enc_key = nil, options = nil)
         
     | 
| 
      
 44 
     | 
    
         
            +
                    ::JWE.encrypt ::JWT.encode(payload, (sig_key || signing_key), 'HS512'), (enc_key || encryption_key), (options || encrypt_options)
         
     | 
| 
      
 45 
     | 
    
         
            +
                  end
         
     | 
| 
      
 46 
     | 
    
         
            +
             
     | 
| 
      
 47 
     | 
    
         
            +
                  alias_method :create, :encode
         
     | 
| 
      
 48 
     | 
    
         
            +
                  alias_method :encrypt, :encode
         
     | 
| 
      
 49 
     | 
    
         
            +
                  alias_method :inflate, :encode
         
     | 
| 
      
 50 
     | 
    
         
            +
             
     | 
| 
      
 51 
     | 
    
         
            +
                  def decode(payload, sig_key = nil, enc_key = nil)
         
     | 
| 
      
 52 
     | 
    
         
            +
                    ::JWT.decode(::JWE.decrypt(payload, (enc_key || encryption_key)), (sig_key || signing_key), true, algorithm: 'HS512')[0]
         
     | 
| 
      
 53 
     | 
    
         
            +
                  end
         
     | 
| 
      
 54 
     | 
    
         
            +
             
     | 
| 
      
 55 
     | 
    
         
            +
                  alias_method :read, :decode
         
     | 
| 
      
 56 
     | 
    
         
            +
                  alias_method :decrypt, :decode
         
     | 
| 
      
 57 
     | 
    
         
            +
                  alias_method :deflate, :decode
         
     | 
| 
      
 58 
     | 
    
         
            +
                end
         
     | 
| 
      
 59 
     | 
    
         
            +
             
     | 
| 
      
 60 
     | 
    
         
            +
                module ControllerMethods
         
     | 
| 
      
 61 
     | 
    
         
            +
                  protected
         
     | 
| 
      
 62 
     | 
    
         
            +
                    def check_user
         
     | 
| 
      
 63 
     | 
    
         
            +
                      if logged_in?
         
     | 
| 
      
 64 
     | 
    
         
            +
                        begin
         
     | 
| 
      
 65 
     | 
    
         
            +
                          data = current_user_session_data
         
     | 
| 
      
 66 
     | 
    
         
            +
                          if  !data[:created_at] ||
         
     | 
| 
      
 67 
     | 
    
         
            +
                              (data[:created_at].to_i > 14.days.ago.to_i)
         
     | 
| 
      
 68 
     | 
    
         
            +
                            if user = session_class.find_by(session_column => data[:user_id])
         
     | 
| 
      
 69 
     | 
    
         
            +
                              session[:current_user] = create_jwt(user, data) if data[:created_at] < 1.hour.ago
         
     | 
| 
      
 70 
     | 
    
         
            +
                              set_user(user)
         
     | 
| 
      
 71 
     | 
    
         
            +
                            else
         
     | 
| 
      
 72 
     | 
    
         
            +
                              throw 'User Not Found'
         
     | 
| 
      
 73 
     | 
    
         
            +
                            end
         
     | 
| 
      
 74 
     | 
    
         
            +
                          else
         
     | 
| 
      
 75 
     | 
    
         
            +
                            throw 'Token Expired'
         
     | 
| 
      
 76 
     | 
    
         
            +
                          end
         
     | 
| 
      
 77 
     | 
    
         
            +
                        rescue
         
     | 
| 
      
 78 
     | 
    
         
            +
                          session.delete(:current_user)
         
     | 
| 
      
 79 
     | 
    
         
            +
                          BetterRecord::Current.drop_values
         
     | 
| 
      
 80 
     | 
    
         
            +
                        end
         
     | 
| 
      
 81 
     | 
    
         
            +
                      end
         
     | 
| 
      
 82 
     | 
    
         
            +
             
     | 
| 
      
 83 
     | 
    
         
            +
                      BetterRecord::Current.user || false
         
     | 
| 
      
 84 
     | 
    
         
            +
                    end
         
     | 
| 
      
 85 
     | 
    
         
            +
             
     | 
| 
      
 86 
     | 
    
         
            +
                    def create_jwt(user, additional_headers = {})
         
     | 
| 
      
 87 
     | 
    
         
            +
                      additional_headers = {} unless additional_headers && additional_headers.is_a?(Hash)
         
     | 
| 
      
 88 
     | 
    
         
            +
                      data = nil
         
     | 
| 
      
 89 
     | 
    
         
            +
                      data = session_data ? session_data.call(user) : {
         
     | 
| 
      
 90 
     | 
    
         
            +
                        user_id: user.__send__(session_column),
         
     | 
| 
      
 91 
     | 
    
         
            +
                        created_at: Time.now.to_i
         
     | 
| 
      
 92 
     | 
    
         
            +
                      }
         
     | 
| 
      
 93 
     | 
    
         
            +
                      BetterRecord::JWT.encode(data.merge(additional_headers.except(*data.keys)))
         
     | 
| 
      
 94 
     | 
    
         
            +
                    end
         
     | 
| 
      
 95 
     | 
    
         
            +
             
     | 
| 
      
 96 
     | 
    
         
            +
                    def create_session_from_certificate(cert)
         
     | 
| 
      
 97 
     | 
    
         
            +
                      user = (certificate_session_class || session_class).
         
     | 
| 
      
 98 
     | 
    
         
            +
                      find_by(certificate_session_column => cert.clean_certificate)
         
     | 
| 
      
 99 
     | 
    
         
            +
             
     | 
| 
      
 100 
     | 
    
         
            +
                      if user
         
     | 
| 
      
 101 
     | 
    
         
            +
                        if  certificate_session_user_method &&
         
     | 
| 
      
 102 
     | 
    
         
            +
                            user.respond_to?(certificate_session_user_method)
         
     | 
| 
      
 103 
     | 
    
         
            +
                          user = user.__send__(certificate_session_user_method)
         
     | 
| 
      
 104 
     | 
    
         
            +
                        end
         
     | 
| 
      
 105 
     | 
    
         
            +
             
     | 
| 
      
 106 
     | 
    
         
            +
                        session[:current_user] = create_jwt(user, { has_certificate: true })
         
     | 
| 
      
 107 
     | 
    
         
            +
                      end
         
     | 
| 
      
 108 
     | 
    
         
            +
                    end
         
     | 
| 
      
 109 
     | 
    
         
            +
             
     | 
| 
      
 110 
     | 
    
         
            +
                    def current_user
         
     | 
| 
      
 111 
     | 
    
         
            +
                      BetterRecord::Current.user || check_user
         
     | 
| 
      
 112 
     | 
    
         
            +
                    end
         
     | 
| 
      
 113 
     | 
    
         
            +
             
     | 
| 
      
 114 
     | 
    
         
            +
                    def current_user_session_data
         
     | 
| 
      
 115 
     | 
    
         
            +
                      logged_in? ? JWT.decode(session[:current_user]).deep_symbolize_keys : {}
         
     | 
| 
      
 116 
     | 
    
         
            +
                    end
         
     | 
| 
      
 117 
     | 
    
         
            +
             
     | 
| 
      
 118 
     | 
    
         
            +
                    def logged_in?
         
     | 
| 
      
 119 
     | 
    
         
            +
                      session[:current_user].present?
         
     | 
| 
      
 120 
     | 
    
         
            +
                    end
         
     | 
| 
      
 121 
     | 
    
         
            +
             
     | 
| 
      
 122 
     | 
    
         
            +
                    def set_user(user)
         
     | 
| 
      
 123 
     | 
    
         
            +
                      BetterRecord::Current.set(user, request.remote_ip)
         
     | 
| 
      
 124 
     | 
    
         
            +
                    end
         
     | 
| 
      
 125 
     | 
    
         
            +
                end
         
     | 
| 
      
 126 
     | 
    
         
            +
              end
         
     | 
| 
      
 127 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,75 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'stringio'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            # Custom matcher to test text written to standard output and standard error
         
     | 
| 
      
 4 
     | 
    
         
            +
            #
         
     | 
| 
      
 5 
     | 
    
         
            +
            # @example
         
     | 
| 
      
 6 
     | 
    
         
            +
            #   expect { $stderr.puts "Some random error" }.to write(/Some.* error/).to(:stderr)
         
     | 
| 
      
 7 
     | 
    
         
            +
            #
         
     | 
| 
      
 8 
     | 
    
         
            +
            # @example
         
     | 
| 
      
 9 
     | 
    
         
            +
            #   expect { $stderr.puts "Some specific error" }.to write('Some specific error').to(:stderr)
         
     | 
| 
      
 10 
     | 
    
         
            +
            #
         
     | 
| 
      
 11 
     | 
    
         
            +
            RSpec::Matchers.define :write do |message|
         
     | 
| 
      
 12 
     | 
    
         
            +
              chain(:to) do |io|
         
     | 
| 
      
 13 
     | 
    
         
            +
                @io = io
         
     | 
| 
      
 14 
     | 
    
         
            +
              end
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
              match do |block|
         
     | 
| 
      
 17 
     | 
    
         
            +
                output =
         
     | 
| 
      
 18 
     | 
    
         
            +
                  case io
         
     | 
| 
      
 19 
     | 
    
         
            +
                  when :stdout then fake_stdout(&block)
         
     | 
| 
      
 20 
     | 
    
         
            +
                  when :stderr  then fake_stderr(&block)
         
     | 
| 
      
 21 
     | 
    
         
            +
                  else fail("Allowed values for `to` are :stdout and :stderr, got `#{io.inspect}`")
         
     | 
| 
      
 22 
     | 
    
         
            +
                  end
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
                case message
         
     | 
| 
      
 25 
     | 
    
         
            +
                when String then output.include? message
         
     | 
| 
      
 26 
     | 
    
         
            +
                when Regexp then output.match message
         
     | 
| 
      
 27 
     | 
    
         
            +
                else fail("Allowed types for write `message` are String or Regexp, got `#{message.class}`")
         
     | 
| 
      
 28 
     | 
    
         
            +
                end
         
     | 
| 
      
 29 
     | 
    
         
            +
              end
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
              def supports_block_expectations?
         
     | 
| 
      
 32 
     | 
    
         
            +
                true # or some logic
         
     | 
| 
      
 33 
     | 
    
         
            +
              end
         
     | 
| 
      
 34 
     | 
    
         
            +
             
     | 
| 
      
 35 
     | 
    
         
            +
              description do
         
     | 
| 
      
 36 
     | 
    
         
            +
                %Q[write #{message.inspect} to #{@io}]
         
     | 
| 
      
 37 
     | 
    
         
            +
              end
         
     | 
| 
      
 38 
     | 
    
         
            +
             
     | 
| 
      
 39 
     | 
    
         
            +
              def f_message(to = 'to')
         
     | 
| 
      
 40 
     | 
    
         
            +
                %Q[expected #{to} #{description} but got #{@buffer.inspect}]
         
     | 
| 
      
 41 
     | 
    
         
            +
              end
         
     | 
| 
      
 42 
     | 
    
         
            +
             
     | 
| 
      
 43 
     | 
    
         
            +
              failure_message do
         
     | 
| 
      
 44 
     | 
    
         
            +
                f_message 'to'
         
     | 
| 
      
 45 
     | 
    
         
            +
              end
         
     | 
| 
      
 46 
     | 
    
         
            +
             
     | 
| 
      
 47 
     | 
    
         
            +
              failure_message_when_negated do
         
     | 
| 
      
 48 
     | 
    
         
            +
                f_message 'not to'
         
     | 
| 
      
 49 
     | 
    
         
            +
              end
         
     | 
| 
      
 50 
     | 
    
         
            +
             
     | 
| 
      
 51 
     | 
    
         
            +
              # Fake STDERR and return a string written to it.
         
     | 
| 
      
 52 
     | 
    
         
            +
              def fake_stderr
         
     | 
| 
      
 53 
     | 
    
         
            +
                original_stderr = $stderr
         
     | 
| 
      
 54 
     | 
    
         
            +
                $stderr = StringIO.new
         
     | 
| 
      
 55 
     | 
    
         
            +
                yield
         
     | 
| 
      
 56 
     | 
    
         
            +
                @buffer = $stderr.string
         
     | 
| 
      
 57 
     | 
    
         
            +
              ensure
         
     | 
| 
      
 58 
     | 
    
         
            +
                $stderr = original_stderr
         
     | 
| 
      
 59 
     | 
    
         
            +
              end
         
     | 
| 
      
 60 
     | 
    
         
            +
             
     | 
| 
      
 61 
     | 
    
         
            +
              # Fake STDOUT and return a string written to it.
         
     | 
| 
      
 62 
     | 
    
         
            +
              def fake_stdout
         
     | 
| 
      
 63 
     | 
    
         
            +
                original_stdout = $stdout
         
     | 
| 
      
 64 
     | 
    
         
            +
                $stdout = StringIO.new
         
     | 
| 
      
 65 
     | 
    
         
            +
                yield
         
     | 
| 
      
 66 
     | 
    
         
            +
                @buffer = $stdout.string
         
     | 
| 
      
 67 
     | 
    
         
            +
              ensure
         
     | 
| 
      
 68 
     | 
    
         
            +
                $stdout = original_stdout
         
     | 
| 
      
 69 
     | 
    
         
            +
              end
         
     | 
| 
      
 70 
     | 
    
         
            +
             
     | 
| 
      
 71 
     | 
    
         
            +
              # default IO is standard output
         
     | 
| 
      
 72 
     | 
    
         
            +
              def io
         
     | 
| 
      
 73 
     | 
    
         
            +
                @io ||= :stdout
         
     | 
| 
      
 74 
     | 
    
         
            +
              end
         
     | 
| 
      
 75 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -7,7 +7,7 @@ class BetterRecord::SetupGenerator < ActiveRecord::Generators::Base 
     | 
|
| 
       7 
7 
     | 
    
         
             
              class_option :eject, type: :boolean, default: false
         
     | 
| 
       8 
8 
     | 
    
         | 
| 
       9 
9 
     | 
    
         
             
              def run_generator
         
     | 
| 
       10 
     | 
    
         
            -
                 
     | 
| 
      
 10 
     | 
    
         
            +
                mount_engine
         
     | 
| 
       11 
11 
     | 
    
         
             
                copy_templates
         
     | 
| 
       12 
12 
     | 
    
         
             
                copy_migrations
         
     | 
| 
       13 
13 
     | 
    
         
             
                gsub_files
         
     | 
| 
         @@ -37,23 +37,6 @@ class BetterRecord::SetupGenerator < ActiveRecord::Generators::Base 
     | 
|
| 
       37 
37 
     | 
    
         
             
                  eject_files if !!options['eject']
         
     | 
| 
       38 
38 
     | 
    
         
             
                end
         
     | 
| 
       39 
39 
     | 
    
         | 
| 
       40 
     | 
    
         
            -
                def gsub_files
         
     | 
| 
       41 
     | 
    
         
            -
                  eager_line = 'config.eager_load_paths += Dir["#{config.root}/lib/modules/**/"]'
         
     | 
| 
       42 
     | 
    
         
            -
                  structure_line = 'config.active_record.schema_format'
         
     | 
| 
       43 
     | 
    
         
            -
             
     | 
| 
       44 
     | 
    
         
            -
                  gsub_file 'config/application.rb', /([ \t]*?(#{Regexp.escape(eager_line)}|#{Regexp.escape(structure_line)})[ ='":]*?(rb|sql)?['"]?[ \t0-9\.]*?)\n/mi do |match|
         
     | 
| 
       45 
     | 
    
         
            -
                    ""
         
     | 
| 
       46 
     | 
    
         
            -
                  end
         
     | 
| 
       47 
     | 
    
         
            -
             
     | 
| 
       48 
     | 
    
         
            -
                  gsub_file 'config/application.rb', /#{Regexp.escape("config.load_defaults")}[ 0-9\.]+\n/mi do |match|
         
     | 
| 
       49 
     | 
    
         
            -
                    "#{match}    #{eager_line}\n    #{structure_line} = :sql\n"
         
     | 
| 
       50 
     | 
    
         
            -
                  end
         
     | 
| 
       51 
     | 
    
         
            -
             
     | 
| 
       52 
     | 
    
         
            -
                  gsub_file 'app/models/application_record.rb', /(#{Regexp.escape("class ApplicationRecord < ActiveRecord::Base")})/mi do |match|
         
     | 
| 
       53 
     | 
    
         
            -
                    "class ApplicationRecord < BetterRecord::Base"
         
     | 
| 
       54 
     | 
    
         
            -
                  end
         
     | 
| 
       55 
     | 
    
         
            -
                end
         
     | 
| 
       56 
     | 
    
         
            -
             
     | 
| 
       57 
40 
     | 
    
         
             
                def eject_files
         
     | 
| 
       58 
41 
     | 
    
         
             
                  template "#{BetterRecord::Engine.root}/db/postgres-audit-trigger.psql", 'db/postgres-audit-trigger.psql'
         
     | 
| 
       59 
42 
     | 
    
         
             
                  template "#{BetterRecord::Engine.root}/lib/better_record.rb", 'lib/better_record.rb'
         
     | 
| 
         @@ -75,6 +58,32 @@ class BetterRecord::SetupGenerator < ActiveRecord::Generators::Base 
     | 
|
| 
       75 
58 
     | 
    
         
             
                  end
         
     | 
| 
       76 
59 
     | 
    
         
             
                end
         
     | 
| 
       77 
60 
     | 
    
         | 
| 
      
 61 
     | 
    
         
            +
                def gsub_files
         
     | 
| 
      
 62 
     | 
    
         
            +
                  eager_line = 'config.eager_load_paths += Dir["#{config.root}/lib/modules/**/"]'
         
     | 
| 
      
 63 
     | 
    
         
            +
                  structure_line = 'config.active_record.schema_format'
         
     | 
| 
      
 64 
     | 
    
         
            +
             
     | 
| 
      
 65 
     | 
    
         
            +
                  gsub_file 'config/application.rb', /([ \t]*?(#{Regexp.escape(eager_line)}|#{Regexp.escape(structure_line)})[ ='":]*?(rb|sql)?['"]?[ \t0-9\.]*?)\n/mi do |match|
         
     | 
| 
      
 66 
     | 
    
         
            +
                    ""
         
     | 
| 
      
 67 
     | 
    
         
            +
                  end
         
     | 
| 
      
 68 
     | 
    
         
            +
             
     | 
| 
      
 69 
     | 
    
         
            +
                  gsub_file 'config/application.rb', /#{Regexp.escape("config.load_defaults")}[ 0-9\.]+\n/mi do |match|
         
     | 
| 
      
 70 
     | 
    
         
            +
                    "#{match}    #{eager_line}\n    #{structure_line} = :sql\n"
         
     | 
| 
      
 71 
     | 
    
         
            +
                  end
         
     | 
| 
      
 72 
     | 
    
         
            +
             
     | 
| 
      
 73 
     | 
    
         
            +
                  gsub_file 'app/models/application_record.rb', /(#{Regexp.escape("class ApplicationRecord < ActiveRecord::Base")})/mi do |match|
         
     | 
| 
      
 74 
     | 
    
         
            +
                    "class ApplicationRecord < BetterRecord::Base"
         
     | 
| 
      
 75 
     | 
    
         
            +
                  end
         
     | 
| 
      
 76 
     | 
    
         
            +
                end
         
     | 
| 
      
 77 
     | 
    
         
            +
             
     | 
| 
      
 78 
     | 
    
         
            +
                def mount_engine
         
     | 
| 
      
 79 
     | 
    
         
            +
                  in_root do
         
     | 
| 
      
 80 
     | 
    
         
            +
                    File.open('config/routes.rb', 'r') do |file|
         
     | 
| 
      
 81 
     | 
    
         
            +
                      return false if file.read =~ /mount\s+BetterRecord::Engine/
         
     | 
| 
      
 82 
     | 
    
         
            +
                    end
         
     | 
| 
      
 83 
     | 
    
         
            +
                  end
         
     | 
| 
      
 84 
     | 
    
         
            +
                  route 'mount BetterRecord::Engine => "/better_record"'
         
     | 
| 
      
 85 
     | 
    
         
            +
                end
         
     | 
| 
      
 86 
     | 
    
         
            +
             
     | 
| 
       78 
87 
     | 
    
         
             
                def migration_path
         
     | 
| 
       79 
88 
     | 
    
         
             
                  if Rails.version >= '5.0.3'
         
     | 
| 
       80 
89 
     | 
    
         
             
                    db_migrate_path
         
     | 
| 
         @@ -1,14 +1,19 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            module BetterRecord
         
     | 
| 
       2 
     | 
    
         
            -
               
     | 
| 
       3 
     | 
    
         
            -
              #    
     | 
| 
       4 
     | 
    
         
            -
              # 
     | 
| 
       5 
     | 
    
         
            -
              # 
     | 
| 
       6 
     | 
    
         
            -
              # 
     | 
| 
       7 
     | 
    
         
            -
              # 
     | 
| 
       8 
     | 
    
         
            -
              # 
     | 
| 
       9 
     | 
    
         
            -
              # 
     | 
| 
       10 
     | 
    
         
            -
              # 
     | 
| 
       11 
     | 
    
         
            -
               
     | 
| 
      
 2 
     | 
    
         
            +
              ##########################################################################
         
     | 
| 
      
 3 
     | 
    
         
            +
              #   THE FOLLOWING SETTINGS CAN ALSO BE SET THROUGH ENVIRONMENT VARIABLES #
         
     | 
| 
      
 4 
     | 
    
         
            +
              #                                                                        #
         
     | 
| 
      
 5 
     | 
    
         
            +
              #       default_polymorphic_method: BR_DEFAULT_POLYMORPHIC_METHOD        #
         
     | 
| 
      
 6 
     | 
    
         
            +
              #                  db_audit_schema: BR_DB_AUDIT_SCHEMA                   #
         
     | 
| 
      
 7 
     | 
    
         
            +
              # has_auditing_relation_by_default: BR_ADD_HAS_MANY                      #
         
     | 
| 
      
 8 
     | 
    
         
            +
              #              audit_relation_name: BR_AUDIT_RELATION_NAME               #
         
     | 
| 
      
 9 
     | 
    
         
            +
              #                  layout_template: BR_LAYOUT_TEMPLATE                   #
         
     | 
| 
      
 10 
     | 
    
         
            +
              #                  app_domain_name: APP_DOMAIN_NAME                      #
         
     | 
| 
      
 11 
     | 
    
         
            +
              #                 after_login_path: BR_AFTER_LOGIN_PATH                  #
         
     | 
| 
      
 12 
     | 
    
         
            +
              #                   session_column: BR_SESSION_COLUMN                    #
         
     | 
| 
      
 13 
     | 
    
         
            +
              #      session_authenticate_method: BR_SESSION_AUTHENTICATE_METHOD       #
         
     | 
| 
      
 14 
     | 
    
         
            +
              #       certificate_session_column: BR_CERTIFICATE_SESSION_COLUMN        #
         
     | 
| 
      
 15 
     | 
    
         
            +
              #  certificate_session_user_method: BR_CERTIFICATE_SESSION_USER_METHOD   #
         
     | 
| 
      
 16 
     | 
    
         
            +
              ##########################################################################
         
     | 
| 
       12 
17 
     | 
    
         | 
| 
       13 
18 
     | 
    
         
             
              # uncomment the following line to use table_names instead of model names
         
     | 
| 
       14 
19 
     | 
    
         
             
              # as the 'type' value in polymorphic relationships
         
     | 
| 
         @@ -39,4 +44,36 @@ module BetterRecord 
     | 
|
| 
       39 
44 
     | 
    
         
             
              # runs under. Used in setting DKIM params. DEFAULT - 'non_existant_domain.com'
         
     | 
| 
       40 
45 
     | 
    
         | 
| 
       41 
46 
     | 
    
         
             
              # self.app_domain_name = 'default_app_name.com'
         
     | 
| 
      
 47 
     | 
    
         
            +
             
     | 
| 
      
 48 
     | 
    
         
            +
              # uncomment and set the session_class to enable gem handled session management
         
     | 
| 
      
 49 
     | 
    
         
            +
              # all other settings are optional
         
     | 
| 
      
 50 
     | 
    
         
            +
             
     | 
| 
      
 51 
     | 
    
         
            +
              # self.session_class = User
         
     | 
| 
      
 52 
     | 
    
         
            +
             
     | 
| 
      
 53 
     | 
    
         
            +
              # OPTIONAL #
         
     | 
| 
      
 54 
     | 
    
         
            +
             
     | 
| 
      
 55 
     | 
    
         
            +
              # self.after_login_path = Rails.application.routes.url_helpers.root_path
         
     | 
| 
      
 56 
     | 
    
         
            +
             
     | 
| 
      
 57 
     | 
    
         
            +
              # self.session_column = :uuid
         
     | 
| 
      
 58 
     | 
    
         
            +
             
     | 
| 
      
 59 
     | 
    
         
            +
              # self.session_data = ->(user) do
         
     | 
| 
      
 60 
     | 
    
         
            +
              #   {
         
     | 
| 
      
 61 
     | 
    
         
            +
              #     user_id: user.uuid,
         
     | 
| 
      
 62 
     | 
    
         
            +
              #     first_access: user.first_login_time,
         
     | 
| 
      
 63 
     | 
    
         
            +
              #     created_at: Time.now
         
     | 
| 
      
 64 
     | 
    
         
            +
              #   }
         
     | 
| 
      
 65 
     | 
    
         
            +
              # end
         
     | 
| 
      
 66 
     | 
    
         
            +
             
     | 
| 
      
 67 
     | 
    
         
            +
              # self.session_authenticate_method = :check_login
         
     | 
| 
      
 68 
     | 
    
         
            +
             
     | 
| 
      
 69 
     | 
    
         
            +
              # self.certificate_session_class = Staff.includes(:user)
         
     | 
| 
      
 70 
     | 
    
         
            +
             
     | 
| 
      
 71 
     | 
    
         
            +
              # self.certificate_session_column = :cert_str
         
     | 
| 
      
 72 
     | 
    
         
            +
             
     | 
| 
      
 73 
     | 
    
         
            +
              # self.certificate_session_user_method = :user
         
     | 
| 
       42 
74 
     | 
    
         
             
            end
         
     | 
| 
      
 75 
     | 
    
         
            +
             
     | 
| 
      
 76 
     | 
    
         
            +
            # uncomment the following lines to set the keys needed for JWT token auth
         
     | 
| 
      
 77 
     | 
    
         
            +
             
     | 
| 
      
 78 
     | 
    
         
            +
            # BetterRecord::JWT.signing_key = ENV.fetch('JWT_SIGNING_KEY') { nil }
         
     | 
| 
      
 79 
     | 
    
         
            +
            # BetterRecord::JWT.encryption_key = ENV.fetch('JWT_ENCRYPTION_KEY') { nil }
         
     | 
    
        metadata
    CHANGED
    
    | 
         @@ -1,14 +1,14 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            --- !ruby/object:Gem::Specification
         
     | 
| 
       2 
2 
     | 
    
         
             
            name: better_record
         
     | 
| 
       3 
3 
     | 
    
         
             
            version: !ruby/object:Gem::Version
         
     | 
| 
       4 
     | 
    
         
            -
              version: 0. 
     | 
| 
      
 4 
     | 
    
         
            +
              version: 0.8.0
         
     | 
| 
       5 
5 
     | 
    
         
             
            platform: ruby
         
     | 
| 
       6 
6 
     | 
    
         
             
            authors:
         
     | 
| 
       7 
7 
     | 
    
         
             
            - Sampson Crowley
         
     | 
| 
       8 
8 
     | 
    
         
             
            autorequire: 
         
     | 
| 
       9 
9 
     | 
    
         
             
            bindir: bin
         
     | 
| 
       10 
10 
     | 
    
         
             
            cert_chain: []
         
     | 
| 
       11 
     | 
    
         
            -
            date: 2018- 
     | 
| 
      
 11 
     | 
    
         
            +
            date: 2018-08-22 00:00:00.000000000 Z
         
     | 
| 
       12 
12 
     | 
    
         
             
            dependencies:
         
     | 
| 
       13 
13 
     | 
    
         
             
            - !ruby/object:Gem::Dependency
         
     | 
| 
       14 
14 
     | 
    
         
             
              name: rails
         
     | 
| 
         @@ -110,6 +110,66 @@ dependencies: 
     | 
|
| 
       110 
110 
     | 
    
         
             
                - - ">="
         
     | 
| 
       111 
111 
     | 
    
         
             
                  - !ruby/object:Gem::Version
         
     | 
| 
       112 
112 
     | 
    
         
             
                    version: 1.5.6
         
     | 
| 
      
 113 
     | 
    
         
            +
            - !ruby/object:Gem::Dependency
         
     | 
| 
      
 114 
     | 
    
         
            +
              name: jwt
         
     | 
| 
      
 115 
     | 
    
         
            +
              requirement: !ruby/object:Gem::Requirement
         
     | 
| 
      
 116 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 117 
     | 
    
         
            +
                - - "~>"
         
     | 
| 
      
 118 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 119 
     | 
    
         
            +
                    version: '2.1'
         
     | 
| 
      
 120 
     | 
    
         
            +
                - - ">="
         
     | 
| 
      
 121 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 122 
     | 
    
         
            +
                    version: 2.1.0
         
     | 
| 
      
 123 
     | 
    
         
            +
              type: :runtime
         
     | 
| 
      
 124 
     | 
    
         
            +
              prerelease: false
         
     | 
| 
      
 125 
     | 
    
         
            +
              version_requirements: !ruby/object:Gem::Requirement
         
     | 
| 
      
 126 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 127 
     | 
    
         
            +
                - - "~>"
         
     | 
| 
      
 128 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 129 
     | 
    
         
            +
                    version: '2.1'
         
     | 
| 
      
 130 
     | 
    
         
            +
                - - ">="
         
     | 
| 
      
 131 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 132 
     | 
    
         
            +
                    version: 2.1.0
         
     | 
| 
      
 133 
     | 
    
         
            +
            - !ruby/object:Gem::Dependency
         
     | 
| 
      
 134 
     | 
    
         
            +
              name: jwe
         
     | 
| 
      
 135 
     | 
    
         
            +
              requirement: !ruby/object:Gem::Requirement
         
     | 
| 
      
 136 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 137 
     | 
    
         
            +
                - - "~>"
         
     | 
| 
      
 138 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 139 
     | 
    
         
            +
                    version: '0.3'
         
     | 
| 
      
 140 
     | 
    
         
            +
                - - ">="
         
     | 
| 
      
 141 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 142 
     | 
    
         
            +
                    version: 0.3.1
         
     | 
| 
      
 143 
     | 
    
         
            +
              type: :runtime
         
     | 
| 
      
 144 
     | 
    
         
            +
              prerelease: false
         
     | 
| 
      
 145 
     | 
    
         
            +
              version_requirements: !ruby/object:Gem::Requirement
         
     | 
| 
      
 146 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 147 
     | 
    
         
            +
                - - "~>"
         
     | 
| 
      
 148 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 149 
     | 
    
         
            +
                    version: '0.3'
         
     | 
| 
      
 150 
     | 
    
         
            +
                - - ">="
         
     | 
| 
      
 151 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 152 
     | 
    
         
            +
                    version: 0.3.1
         
     | 
| 
      
 153 
     | 
    
         
            +
            - !ruby/object:Gem::Dependency
         
     | 
| 
      
 154 
     | 
    
         
            +
              name: csv
         
     | 
| 
      
 155 
     | 
    
         
            +
              requirement: !ruby/object:Gem::Requirement
         
     | 
| 
      
 156 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 157 
     | 
    
         
            +
                - - "~>"
         
     | 
| 
      
 158 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 159 
     | 
    
         
            +
                    version: '3.0'
         
     | 
| 
      
 160 
     | 
    
         
            +
                - - ">="
         
     | 
| 
      
 161 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 162 
     | 
    
         
            +
                    version: 3.0.0
         
     | 
| 
      
 163 
     | 
    
         
            +
              type: :runtime
         
     | 
| 
      
 164 
     | 
    
         
            +
              prerelease: false
         
     | 
| 
      
 165 
     | 
    
         
            +
              version_requirements: !ruby/object:Gem::Requirement
         
     | 
| 
      
 166 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 167 
     | 
    
         
            +
                - - "~>"
         
     | 
| 
      
 168 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 169 
     | 
    
         
            +
                    version: '3.0'
         
     | 
| 
      
 170 
     | 
    
         
            +
                - - ">="
         
     | 
| 
      
 171 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 172 
     | 
    
         
            +
                    version: 3.0.0
         
     | 
| 
       113 
173 
     | 
    
         
             
            - !ruby/object:Gem::Dependency
         
     | 
| 
       114 
174 
     | 
    
         
             
              name: rspec-rails
         
     | 
| 
       115 
175 
     | 
    
         
             
              requirement: !ruby/object:Gem::Requirement
         
     | 
| 
         @@ -188,6 +248,7 @@ files: 
     | 
|
| 
       188 
248 
     | 
    
         
             
            - config/initializers/core_ext/boolean.rb
         
     | 
| 
       189 
249 
     | 
    
         
             
            - config/initializers/core_ext/date.rb
         
     | 
| 
       190 
250 
     | 
    
         
             
            - config/initializers/core_ext/integer.rb
         
     | 
| 
      
 251 
     | 
    
         
            +
            - config/initializers/core_ext/string.rb
         
     | 
| 
       191 
252 
     | 
    
         
             
            - config/initializers/dkim.rb
         
     | 
| 
       192 
253 
     | 
    
         
             
            - config/initializers/filter_parameter_logging.rb
         
     | 
| 
       193 
254 
     | 
    
         
             
            - config/initializers/inflections.rb
         
     | 
| 
         @@ -205,13 +266,20 @@ files: 
     | 
|
| 
       205 
266 
     | 
    
         
             
            - lib/better_record/concerns/active_record_extensions/associations_extensions/builder_extensions/association_extensions.rb
         
     | 
| 
       206 
267 
     | 
    
         
             
            - lib/better_record/concerns/active_record_extensions/base_extensions.rb
         
     | 
| 
       207 
268 
     | 
    
         
             
            - lib/better_record/concerns/active_record_extensions/reflection_extensions.rb
         
     | 
| 
      
 269 
     | 
    
         
            +
            - lib/better_record/concerns/controllers/authenticatable.rb
         
     | 
| 
      
 270 
     | 
    
         
            +
            - lib/better_record/concerns/controllers/sessionable.rb
         
     | 
| 
      
 271 
     | 
    
         
            +
            - lib/better_record/concerns/controllers/uploadable.rb
         
     | 
| 
      
 272 
     | 
    
         
            +
            - lib/better_record/encoder.rb
         
     | 
| 
       208 
273 
     | 
    
         
             
            - lib/better_record/engine.rb
         
     | 
| 
       209 
274 
     | 
    
         
             
            - lib/better_record/fake_redis.rb
         
     | 
| 
      
 275 
     | 
    
         
            +
            - lib/better_record/jwt.rb
         
     | 
| 
       210 
276 
     | 
    
         
             
            - lib/better_record/migration.rb
         
     | 
| 
       211 
277 
     | 
    
         
             
            - lib/better_record/nullify_blank_attributes.rb
         
     | 
| 
       212 
278 
     | 
    
         
             
            - lib/better_record/polymorphic_override.rb
         
     | 
| 
       213 
279 
     | 
    
         
             
            - lib/better_record/railtie.rb
         
     | 
| 
       214 
280 
     | 
    
         
             
            - lib/better_record/relation.rb
         
     | 
| 
      
 281 
     | 
    
         
            +
            - lib/better_record/rspec/expectations.rb
         
     | 
| 
      
 282 
     | 
    
         
            +
            - lib/better_record/rspec/expectations/write.rb
         
     | 
| 
       215 
283 
     | 
    
         
             
            - lib/better_record/rspec/extensions.rb
         
     | 
| 
       216 
284 
     | 
    
         
             
            - lib/better_record/rspec/extensions/boolean_column.rb
         
     | 
| 
       217 
285 
     | 
    
         
             
            - lib/better_record/rspec/extensions/has_valid_factory.rb
         
     | 
| 
         @@ -256,7 +324,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement 
     | 
|
| 
       256 
324 
     | 
    
         
             
                  version: '0'
         
     | 
| 
       257 
325 
     | 
    
         
             
            requirements: []
         
     | 
| 
       258 
326 
     | 
    
         
             
            rubyforge_project: 
         
     | 
| 
       259 
     | 
    
         
            -
            rubygems_version: 2.7. 
     | 
| 
      
 327 
     | 
    
         
            +
            rubygems_version: 2.7.7
         
     | 
| 
       260 
328 
     | 
    
         
             
            signing_key: 
         
     | 
| 
       261 
329 
     | 
    
         
             
            specification_version: 4
         
     | 
| 
       262 
330 
     | 
    
         
             
            summary: Fix functions that are lacking in Active record to be compatible with multi-app
         
     |