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
|