masks 0.4.0 → 0.6.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/CHANGELOG.md +29 -0
- data/LICENSE +21 -0
- data/README.md +235 -29
- data/app/controllers/masks/rails/avatars_controller.rb +51 -0
- data/app/controllers/masks/rails/base_controller.rb +13 -0
- data/app/controllers/masks/rails/handshakes_controller.rb +86 -0
- data/app/controllers/masks/rails/sessions_controller.rb +118 -0
- data/app/views/layouts/masks/rails/plain.html.erb +47 -0
- data/app/views/masks/rails/handshakes/refused.html.erb +12 -0
- data/app/views/masks/rails/handshakes/show.html.erb +40 -0
- data/config/routes.rb +11 -82
- data/lib/generators/masks/install/install_generator.rb +35 -22
- data/lib/generators/masks/install/templates/masks.rb.tt +38 -0
- data/lib/masks/client/claims.rb +144 -0
- data/lib/masks/client/errors.rb +60 -0
- data/lib/masks/client/handshake.rb +104 -0
- data/lib/masks/client/http.rb +96 -0
- data/lib/masks/client/introspection.rb +29 -0
- data/lib/masks/client/issuer.rb +92 -0
- data/lib/masks/client/pkce.rb +27 -0
- data/lib/masks/client/rack.rb +62 -0
- data/lib/masks/client/registration.rb +115 -0
- data/lib/masks/client/registry.rb +25 -0
- data/lib/masks/client/resource.rb +92 -0
- data/lib/masks/client/session.rb +146 -0
- data/lib/masks/client/stores.rb +40 -0
- data/lib/masks/client/tokens.rb +70 -0
- data/lib/masks/client/tracker.rb +122 -0
- data/lib/masks/client/verifier.rb +42 -0
- data/lib/masks/client.rb +51 -0
- data/lib/masks/rails/authentication.rb +260 -0
- data/lib/masks/rails/configurable.rb +11 -0
- data/lib/masks/rails/configuration.rb +184 -0
- data/lib/masks/rails/credentials.rb +60 -0
- data/lib/masks/rails/engine.rb +20 -0
- data/lib/masks/rails/protected_resource.rb +51 -0
- data/lib/masks/rails.rb +10 -0
- data/lib/masks/version.rb +1 -3
- data/lib/masks.rb +3 -183
- metadata +48 -416
- data/MIT-LICENSE +0 -20
- data/Rakefile +0 -11
- data/app/assets/builds/masks/application.css +0 -1
- data/app/assets/builds/masks/application.js +0 -8549
- data/app/assets/builds/masks/application.js.map +0 -7
- data/app/assets/images/masks.png +0 -0
- data/app/assets/javascripts/application.js +0 -2
- data/app/assets/javascripts/controllers/application.js +0 -9
- data/app/assets/javascripts/controllers/emails_controller.js +0 -28
- data/app/assets/javascripts/controllers/index.js +0 -21
- data/app/assets/javascripts/controllers/keys_controller.js +0 -20
- data/app/assets/javascripts/controllers/recover_controller.js +0 -21
- data/app/assets/javascripts/controllers/recover_password_controller.js +0 -21
- data/app/assets/javascripts/controllers/session_controller.js +0 -94
- data/app/assets/javascripts/controllers/table_controller.js +0 -15
- data/app/assets/manifest.js +0 -2
- data/app/assets/masks_manifest.js +0 -2
- data/app/assets/stylesheets/application.css +0 -34
- data/app/controllers/concerns/masks/controller.rb +0 -114
- data/app/controllers/masks/actors_controller.rb +0 -15
- data/app/controllers/masks/application_controller.rb +0 -35
- data/app/controllers/masks/backup_codes_controller.rb +0 -34
- data/app/controllers/masks/debug_controller.rb +0 -9
- data/app/controllers/masks/devices_controller.rb +0 -20
- data/app/controllers/masks/emails_controller.rb +0 -60
- data/app/controllers/masks/error_controller.rb +0 -14
- data/app/controllers/masks/keys_controller.rb +0 -45
- data/app/controllers/masks/manage/actors_controller.rb +0 -83
- data/app/controllers/masks/manage/base_controller.rb +0 -20
- data/app/controllers/masks/manage/clients_controller.rb +0 -84
- data/app/controllers/masks/manage/dashboard_controller.rb +0 -15
- data/app/controllers/masks/manage/devices_controller.rb +0 -19
- data/app/controllers/masks/one_time_code_controller.rb +0 -49
- data/app/controllers/masks/openid/authorizations_controller.rb +0 -45
- data/app/controllers/masks/openid/discoveries_controller.rb +0 -55
- data/app/controllers/masks/openid/tokens_controller.rb +0 -45
- data/app/controllers/masks/openid/userinfo_controller.rb +0 -28
- data/app/controllers/masks/passwords_controller.rb +0 -33
- data/app/controllers/masks/recoveries_controller.rb +0 -43
- data/app/controllers/masks/sessions_controller.rb +0 -53
- data/app/helpers/masks/application_helper.rb +0 -49
- data/app/jobs/masks/application_job.rb +0 -7
- data/app/jobs/masks/expire_actors_job.rb +0 -15
- data/app/jobs/masks/expire_recoveries_job.rb +0 -15
- data/app/mailers/masks/actor_mailer.rb +0 -22
- data/app/mailers/masks/application_mailer.rb +0 -15
- data/app/models/concerns/masks/access.rb +0 -162
- data/app/models/concerns/masks/actor.rb +0 -132
- data/app/models/concerns/masks/adapter.rb +0 -68
- data/app/models/concerns/masks/role.rb +0 -9
- data/app/models/concerns/masks/scoped.rb +0 -54
- data/app/models/masks/access/actor_password.rb +0 -21
- data/app/models/masks/access/actor_scopes.rb +0 -18
- data/app/models/masks/access/actor_signup.rb +0 -21
- data/app/models/masks/actors/anonymous.rb +0 -40
- data/app/models/masks/actors/system.rb +0 -24
- data/app/models/masks/adapters/active_record.rb +0 -85
- data/app/models/masks/application_model.rb +0 -15
- data/app/models/masks/application_record.rb +0 -8
- data/app/models/masks/check.rb +0 -192
- data/app/models/masks/credential.rb +0 -166
- data/app/models/masks/credentials/access_token.rb +0 -60
- data/app/models/masks/credentials/backup_code.rb +0 -30
- data/app/models/masks/credentials/device.rb +0 -59
- data/app/models/masks/credentials/email.rb +0 -48
- data/app/models/masks/credentials/factor2.rb +0 -71
- data/app/models/masks/credentials/key.rb +0 -38
- data/app/models/masks/credentials/last_login.rb +0 -12
- data/app/models/masks/credentials/masquerade.rb +0 -32
- data/app/models/masks/credentials/nickname.rb +0 -63
- data/app/models/masks/credentials/one_time_code.rb +0 -34
- data/app/models/masks/credentials/password.rb +0 -28
- data/app/models/masks/credentials/recovery.rb +0 -71
- data/app/models/masks/credentials/return_to.rb +0 -27
- data/app/models/masks/credentials/session.rb +0 -67
- data/app/models/masks/device.rb +0 -30
- data/app/models/masks/error.rb +0 -51
- data/app/models/masks/event.rb +0 -14
- data/app/models/masks/mask.rb +0 -266
- data/app/models/masks/openid/authorization.rb +0 -116
- data/app/models/masks/openid/token.rb +0 -56
- data/app/models/masks/rails/actor.rb +0 -212
- data/app/models/masks/rails/actor_role.rb +0 -12
- data/app/models/masks/rails/device.rb +0 -47
- data/app/models/masks/rails/email.rb +0 -96
- data/app/models/masks/rails/key.rb +0 -61
- data/app/models/masks/rails/openid/access_token.rb +0 -55
- data/app/models/masks/rails/openid/authorization.rb +0 -45
- data/app/models/masks/rails/openid/client.rb +0 -186
- data/app/models/masks/rails/openid/id_token.rb +0 -43
- data/app/models/masks/rails/recovery.rb +0 -116
- data/app/models/masks/rails/role.rb +0 -20
- data/app/models/masks/rails/scope.rb +0 -15
- data/app/models/masks/session.rb +0 -447
- data/app/models/masks/sessions/access.rb +0 -27
- data/app/models/masks/sessions/inline.rb +0 -16
- data/app/models/masks/sessions/request.rb +0 -42
- data/app/resources/masks/actor_resource.rb +0 -9
- data/app/resources/masks/session_resource.rb +0 -15
- data/app/views/layouts/masks/application.html.erb +0 -17
- data/app/views/layouts/masks/mailer.html.erb +0 -17
- data/app/views/layouts/masks/mailer.text.erb +0 -1
- data/app/views/layouts/masks/manage.html.erb +0 -42
- data/app/views/masks/actor_mailer/recover_credentials.html.erb +0 -32
- data/app/views/masks/actor_mailer/recover_credentials.text.erb +0 -1
- data/app/views/masks/actor_mailer/verify_email.html.erb +0 -33
- data/app/views/masks/actor_mailer/verify_email.text.erb +0 -8
- data/app/views/masks/actors/current.html.erb +0 -145
- data/app/views/masks/application/_header.html.erb +0 -30
- data/app/views/masks/backup_codes/new.html.erb +0 -117
- data/app/views/masks/emails/new.html.erb +0 -109
- data/app/views/masks/emails/verify.html.erb +0 -51
- data/app/views/masks/keys/new.html.erb +0 -127
- data/app/views/masks/manage/actors/index.html.erb +0 -104
- data/app/views/masks/manage/actors/show.html.erb +0 -172
- data/app/views/masks/manage/clients/index.html.erb +0 -102
- data/app/views/masks/manage/clients/show.html.erb +0 -156
- data/app/views/masks/manage/dashboard/index.html.erb +0 -10
- data/app/views/masks/manage/devices/index.html.erb +0 -47
- data/app/views/masks/one_time_code/new.html.erb +0 -167
- data/app/views/masks/openid/authorizations/error.html.erb +0 -23
- data/app/views/masks/openid/authorizations/new.html.erb +0 -46
- data/app/views/masks/passwords/edit.html.erb +0 -71
- data/app/views/masks/recoveries/new.html.erb +0 -69
- data/app/views/masks/recoveries/password.html.erb +0 -63
- data/app/views/masks/sessions/new.html.erb +0 -152
- data/config/brakeman.ignore +0 -28
- data/config/initializers/inflections.rb +0 -5
- data/config/locales/en.yml +0 -307
- data/db/migrate/20231205173845_create_actors.rb +0 -94
- data/db/migrate/20240329182422_support_openid.rb +0 -64
- data/lib/generators/masks/install/USAGE +0 -8
- data/lib/generators/masks/install/templates/initializer.rb +0 -5
- data/lib/generators/masks/install/templates/masks.json +0 -9
- data/lib/masks/configuration.rb +0 -249
- data/lib/masks/engine.rb +0 -25
- data/lib/masks/middleware.rb +0 -70
- data/lib/tasks/masks_tasks.rake +0 -72
- data/masks.json +0 -315
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
module Masks
|
|
2
|
+
module Rails
|
|
3
|
+
# The default place a single-tenant app keeps what the handshake gives it,
|
|
4
|
+
# so `config.store` has something to be before a consumer writes one. An
|
|
5
|
+
# app with more than one issuer wants its own — `things` keeps these on
|
|
6
|
+
# `tenants`, because a handshake is per tenant there.
|
|
7
|
+
class Credentials
|
|
8
|
+
KEYS = %w[client_id client_secret registration_access_token registration_client_uri].freeze
|
|
9
|
+
|
|
10
|
+
attr_reader :path
|
|
11
|
+
|
|
12
|
+
def initialize(path)
|
|
13
|
+
@path = Pathname.new(path)
|
|
14
|
+
@lock = Mutex.new
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def read
|
|
18
|
+
@lock.synchronize { held }
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def write(registration)
|
|
22
|
+
@lock.synchronize do
|
|
23
|
+
@held = {
|
|
24
|
+
"client_id" => registration.client_id,
|
|
25
|
+
"client_secret" => registration.client_secret,
|
|
26
|
+
"registration_access_token" => registration.access_token,
|
|
27
|
+
"registration_client_uri" => registration.uri,
|
|
28
|
+
"connected_at" => Time.now.utc.iso8601
|
|
29
|
+
}.compact
|
|
30
|
+
|
|
31
|
+
path.dirname.mkpath
|
|
32
|
+
path.write(JSON.pretty_generate(@held))
|
|
33
|
+
path.chmod(0o600)
|
|
34
|
+
@held
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def clear!
|
|
39
|
+
@lock.synchronize do
|
|
40
|
+
@held = nil
|
|
41
|
+
path.delete if path.exist?
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def connected?
|
|
46
|
+
read["client_id"].present?
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
private
|
|
50
|
+
|
|
51
|
+
def held
|
|
52
|
+
return @held if defined?(@held) && @held
|
|
53
|
+
|
|
54
|
+
@held = path.exist? ? JSON.parse(path.read) : {}
|
|
55
|
+
rescue JSON::ParserError
|
|
56
|
+
@held = {}
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
module Masks
|
|
2
|
+
module Rails
|
|
3
|
+
class Engine < ::Rails::Engine
|
|
4
|
+
isolate_namespace Masks::Rails
|
|
5
|
+
|
|
6
|
+
config.masks = Masks::Rails.config
|
|
7
|
+
|
|
8
|
+
# Opt-in, not blanket. This used to `include Masks::Rails::Authentication`
|
|
9
|
+
# into every controller in the host app, which lands twenty-five `masks_*`
|
|
10
|
+
# methods and four helper_methods on code the consumer owns, with no way
|
|
11
|
+
# to say no — and a name collision found that way is the kind of thing
|
|
12
|
+
# `grants:` versus `scope:` already cost this project once.
|
|
13
|
+
initializer "masks.authentication" do
|
|
14
|
+
ActiveSupport.on_load(:action_controller) do
|
|
15
|
+
include Masks::Rails::Authentication if Masks::Rails.config.authenticate_everything
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
module Masks
|
|
2
|
+
module Rails
|
|
3
|
+
module ProtectedResource
|
|
4
|
+
extend ActiveSupport::Concern
|
|
5
|
+
include Masks::Rails::Configurable
|
|
6
|
+
|
|
7
|
+
class_methods do
|
|
8
|
+
def masks_protect!(**options)
|
|
9
|
+
before_action(-> { masks_authenticate!(**options) }, **options.slice(:only, :except))
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def masks_resource
|
|
14
|
+
@masks_resource ||= masks_config.resource_server_for(request)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def masks_claims
|
|
18
|
+
@masks_claims if defined?(@masks_claims)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def masks_authenticate!(scope: nil, **)
|
|
22
|
+
@masks_claims = masks_resource.authenticate(request.authorization, scope: scope)
|
|
23
|
+
rescue Masks::Client::Challenge => e
|
|
24
|
+
masks_challenge(e)
|
|
25
|
+
false
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def masks_authenticate(scope: nil)
|
|
29
|
+
masks_resource.authenticate(request.authorization, scope: scope)
|
|
30
|
+
rescue Masks::Client::Unauthenticated
|
|
31
|
+
nil
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def masks_challenge(error)
|
|
35
|
+
error = Masks::Client::Unauthorized.new(error.to_s) unless error.is_a?(Masks::Client::Challenge)
|
|
36
|
+
|
|
37
|
+
response.headers["WWW-Authenticate"] = masks_resource.challenge(error)
|
|
38
|
+
response.headers["Cache-Control"] = "no-store"
|
|
39
|
+
|
|
40
|
+
render json: {
|
|
41
|
+
"error" => error.code || "invalid_token",
|
|
42
|
+
"error_description" => error.description
|
|
43
|
+
}, status: error.status
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def masks_resource_metadata
|
|
47
|
+
masks_resource.metadata
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
data/lib/masks/rails.rb
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
require "rails"
|
|
2
|
+
|
|
3
|
+
require_relative "version"
|
|
4
|
+
require_relative "client"
|
|
5
|
+
require_relative "rails/credentials"
|
|
6
|
+
require_relative "rails/configuration"
|
|
7
|
+
require_relative "rails/configurable"
|
|
8
|
+
require_relative "rails/authentication"
|
|
9
|
+
require_relative "rails/protected_resource"
|
|
10
|
+
require_relative "rails/engine"
|
data/lib/masks/version.rb
CHANGED
data/lib/masks.rb
CHANGED
|
@@ -1,184 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
require_relative "masks/version"
|
|
2
|
+
require_relative "masks/client"
|
|
2
3
|
|
|
3
|
-
|
|
4
|
-
require "masks/engine"
|
|
5
|
-
require "masks/configuration"
|
|
6
|
-
require "fuzzyurl"
|
|
7
|
-
require "valid_email"
|
|
8
|
-
require "phonelib"
|
|
9
|
-
require "rqrcode"
|
|
10
|
-
require "rotp"
|
|
11
|
-
require "alba"
|
|
12
|
-
require "pagy"
|
|
13
|
-
require "device_detector"
|
|
14
|
-
require "active_model"
|
|
15
|
-
require "chronic_duration"
|
|
16
|
-
|
|
17
|
-
# Top-level module for masks.
|
|
18
|
-
#
|
|
19
|
-
# Includes helper methods for managing configuration and building
|
|
20
|
-
# sessions, access, etc.
|
|
21
|
-
module Masks
|
|
22
|
-
# @visibility private
|
|
23
|
-
ANON = :anon
|
|
24
|
-
|
|
25
|
-
class << self
|
|
26
|
-
# Returns an access instance based on the type & session passed.
|
|
27
|
-
#
|
|
28
|
-
# @param [Symbol|String] name
|
|
29
|
-
# @param [Masks::Session] session
|
|
30
|
-
# @return [Masks::Access]
|
|
31
|
-
# @raise [Masks::Error::Unauthorized] if access cannot be granted to the session passed
|
|
32
|
-
# @raise [Masks::UnknownAccess] if the access type cannot be found
|
|
33
|
-
def access(name, session, **_opts)
|
|
34
|
-
configuration.access(name).fetch(:cls).build(session)
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
# Returns a masked session based on the request passed.
|
|
38
|
-
#
|
|
39
|
-
# @param [ActionDispatch::Request] request
|
|
40
|
-
# @return [Masks::Sessions::Request] session
|
|
41
|
-
def request(request)
|
|
42
|
-
model = configuration.model(:request)
|
|
43
|
-
session = model.new(config: configuration, request:)
|
|
44
|
-
session.mask!
|
|
45
|
-
session
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
# Returns a masked session based on the params and data passed.
|
|
49
|
-
#
|
|
50
|
-
# This method is useful for creating masks directly, outside of a
|
|
51
|
-
# specific context like a web request.
|
|
52
|
-
#
|
|
53
|
-
# @param params [Hash]
|
|
54
|
-
# @param data [Hash]
|
|
55
|
-
# @yield [Masks::Sessions::Inline]
|
|
56
|
-
# @return [Masks::Sessions::Inline] session
|
|
57
|
-
def mask(name, params: {}, **data)
|
|
58
|
-
model = configuration.model(:inline)
|
|
59
|
-
session = model.new(name:, config: configuration, params:, data:)
|
|
60
|
-
session.mask!
|
|
61
|
-
yield session if session.passed? && block_given?
|
|
62
|
-
session
|
|
63
|
-
end
|
|
64
|
-
|
|
65
|
-
# Yields the global masks configuration object.
|
|
66
|
-
# @return [Masks::Configuration]
|
|
67
|
-
# @yield [Masks::Configuration]
|
|
68
|
-
def configure
|
|
69
|
-
yield configuration
|
|
70
|
-
end
|
|
71
|
-
|
|
72
|
-
# Returns the global configuration object for masks.
|
|
73
|
-
# @return [Masks::Configuration]
|
|
74
|
-
def configuration
|
|
75
|
-
@configuration ||= Masks::Configuration.new(data: config.dup)
|
|
76
|
-
end
|
|
77
|
-
|
|
78
|
-
# @visibility private
|
|
79
|
-
def event(name, **opts, &block)
|
|
80
|
-
ActiveSupport::Notifications.instrument("masks.#{name}", **opts) do
|
|
81
|
-
block.call
|
|
82
|
-
end
|
|
83
|
-
end
|
|
84
|
-
|
|
85
|
-
# @visibility private
|
|
86
|
-
def config
|
|
87
|
-
@config ||=
|
|
88
|
-
begin
|
|
89
|
-
config = load_config(config_path)
|
|
90
|
-
|
|
91
|
-
defaults =
|
|
92
|
-
if config[:extend]
|
|
93
|
-
# extend a "masks.json" from a gem
|
|
94
|
-
load_config(gem_path(config[:extend]))
|
|
95
|
-
else
|
|
96
|
-
{}
|
|
97
|
-
end
|
|
98
|
-
|
|
99
|
-
config = defaults.except(:masks).deep_merge(config)
|
|
100
|
-
config[:masks] = [*config[:masks], *defaults[:masks]] if defaults[
|
|
101
|
-
:masks
|
|
102
|
-
]
|
|
103
|
-
config
|
|
104
|
-
end
|
|
105
|
-
end
|
|
106
|
-
|
|
107
|
-
# @visibility private
|
|
108
|
-
def with_config(path_or_config)
|
|
109
|
-
previous_config = @config
|
|
110
|
-
previous_path = @config_path
|
|
111
|
-
|
|
112
|
-
case path_or_config
|
|
113
|
-
when String
|
|
114
|
-
@config_path = Pathname.new(path_or_config)
|
|
115
|
-
when Pathname
|
|
116
|
-
@config_path = path_or_config
|
|
117
|
-
when Hash
|
|
118
|
-
@config_path = :custom
|
|
119
|
-
@config = path_or_config
|
|
120
|
-
else
|
|
121
|
-
raise Error::InvalidConfiguration, path_or_config
|
|
122
|
-
end
|
|
123
|
-
|
|
124
|
-
result = yield
|
|
125
|
-
ensure
|
|
126
|
-
@config = previous_config
|
|
127
|
-
@config_path = previous_path
|
|
128
|
-
|
|
129
|
-
result
|
|
130
|
-
end
|
|
131
|
-
|
|
132
|
-
# @visibility private
|
|
133
|
-
def config_path
|
|
134
|
-
path =
|
|
135
|
-
[
|
|
136
|
-
@config_path,
|
|
137
|
-
ENV["MASKS_DIR"] ? Pathname.new(ENV["MASKS_DIR"]) : nil,
|
|
138
|
-
Pathname.new(Dir.pwd),
|
|
139
|
-
defined?(ENGINE_ROOT) ? Pathname.new(ENGINE_ROOT) : nil
|
|
140
|
-
].find do |p|
|
|
141
|
-
p.is_a?(Symbol) || (p && File.exist?(p.join("masks.json")))
|
|
142
|
-
end
|
|
143
|
-
|
|
144
|
-
raise Error::ConfigurationNotFound unless path
|
|
145
|
-
|
|
146
|
-
path
|
|
147
|
-
end
|
|
148
|
-
|
|
149
|
-
# @visibility private
|
|
150
|
-
def config_path=(value)
|
|
151
|
-
@config_path =
|
|
152
|
-
case value
|
|
153
|
-
when String
|
|
154
|
-
Pathname.new(value)
|
|
155
|
-
when Pathname
|
|
156
|
-
value
|
|
157
|
-
else
|
|
158
|
-
raise Error::InvalidConfiguration, value
|
|
159
|
-
end
|
|
160
|
-
end
|
|
161
|
-
|
|
162
|
-
# @visibility private
|
|
163
|
-
def reset!
|
|
164
|
-
@configuration = @config = @config_path = nil
|
|
165
|
-
end
|
|
166
|
-
|
|
167
|
-
def load_config(dir)
|
|
168
|
-
JSON.parse(File.read(dir.join("masks.json")), symbolize_names: true)
|
|
169
|
-
end
|
|
170
|
-
|
|
171
|
-
def gem_path(gem_name)
|
|
172
|
-
begin
|
|
173
|
-
# Try to require the gem
|
|
174
|
-
require gem_name
|
|
175
|
-
rescue LoadError
|
|
176
|
-
return nil
|
|
177
|
-
end
|
|
178
|
-
|
|
179
|
-
# Get the gem specification
|
|
180
|
-
spec = Gem::Specification.find_by_name(gem_name)
|
|
181
|
-
Pathname.new(spec.gem_dir) if spec
|
|
182
|
-
end
|
|
183
|
-
end
|
|
184
|
-
end
|
|
4
|
+
require_relative "masks/rails" if defined?(::Rails::Engine)
|