better_record 0.7.5 → 0.8.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|