lotusrb 0.1.0 → 0.2.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 +53 -0
- data/README.md +241 -311
- data/bin/lotus +4 -0
- data/lib/lotus/application.rb +111 -15
- data/lib/lotus/cli.rb +85 -0
- data/lib/lotus/commands/console.rb +62 -0
- data/lib/lotus/commands/new.rb +32 -0
- data/lib/lotus/commands/routes.rb +14 -0
- data/lib/lotus/commands/server.rb +65 -0
- data/lib/lotus/config/assets.rb +24 -10
- data/lib/lotus/config/configure.rb +17 -0
- data/lib/lotus/config/framework_configuration.rb +30 -0
- data/lib/lotus/config/load_paths.rb +1 -1
- data/lib/lotus/config/sessions.rb +97 -0
- data/lib/lotus/configuration.rb +698 -40
- data/lib/lotus/container.rb +30 -0
- data/lib/lotus/environment.rb +377 -0
- data/lib/lotus/frameworks.rb +17 -28
- data/lib/lotus/generators/abstract.rb +31 -0
- data/lib/lotus/generators/application/container/.gitkeep +1 -0
- data/lib/lotus/generators/application/container/Gemfile.tt +29 -0
- data/lib/lotus/generators/application/container/Rakefile.minitest.tt +10 -0
- data/lib/lotus/generators/application/container/config/.env.development.tt +2 -0
- data/lib/lotus/generators/application/container/config/.env.test.tt +2 -0
- data/lib/lotus/generators/application/container/config/.env.tt +1 -0
- data/lib/lotus/generators/application/container/config/environment.rb.tt +7 -0
- data/lib/lotus/generators/application/container/config.ru.tt +3 -0
- data/lib/lotus/generators/application/container/db/.gitkeep +1 -0
- data/lib/lotus/generators/application/container/features_helper.rb.tt +11 -0
- data/lib/lotus/generators/application/container/lib/app_name.rb.tt +31 -0
- data/lib/lotus/generators/application/container/lib/chirp/entities/.gitkeep +1 -0
- data/lib/lotus/generators/application/container/lib/chirp/repositories/.gitkeep +1 -0
- data/lib/lotus/generators/application/container/spec_helper.rb.tt +7 -0
- data/lib/lotus/generators/application/container.rb +70 -0
- data/lib/lotus/generators/slice/.gitkeep.tt +1 -0
- data/lib/lotus/generators/slice/action.rb.tt +8 -0
- data/lib/lotus/generators/slice/application.rb.tt +182 -0
- data/lib/lotus/generators/slice/config/mapping.rb.tt +10 -0
- data/lib/lotus/generators/slice/config/routes.rb.tt +8 -0
- data/lib/lotus/generators/slice/templates/application.html.erb +9 -0
- data/lib/lotus/generators/slice/templates/application.html.erb.tt +9 -0
- data/lib/lotus/generators/slice/templates/template.html.erb.tt +2 -0
- data/lib/lotus/generators/slice/view.rb.tt +5 -0
- data/lib/lotus/generators/slice/views/application_layout.rb.tt +7 -0
- data/lib/lotus/generators/slice.rb +103 -0
- data/lib/lotus/loader.rb +99 -19
- data/lib/lotus/middleware.rb +92 -9
- data/lib/lotus/rendering_policy.rb +42 -19
- data/lib/lotus/routing/default.rb +1 -1
- data/lib/lotus/setup.rb +5 -0
- data/lib/lotus/templates/welcome.html +49 -0
- data/lib/lotus/version.rb +1 -1
- data/lib/lotus/views/default.rb +13 -0
- data/lib/lotus/views/default_template_finder.rb +19 -0
- data/lib/lotus/welcome.rb +14 -0
- data/lib/lotus.rb +1 -0
- data/lotusrb.gemspec +9 -5
- metadata +122 -36
data/lib/lotus/application.rb
CHANGED
@@ -14,22 +14,47 @@ module Lotus
|
|
14
14
|
# require 'lotus'
|
15
15
|
#
|
16
16
|
# module Bookshelf
|
17
|
-
# Application < Lotus::Application
|
17
|
+
# class Application < Lotus::Application
|
18
18
|
# end
|
19
19
|
# end
|
20
20
|
class Application
|
21
|
-
|
21
|
+
# Override Ruby's Class#inherited
|
22
|
+
#
|
23
|
+
# @since 0.2.0
|
24
|
+
# @api private
|
25
|
+
#
|
26
|
+
# @see http://www.ruby-doc.org/core/Class.html#method-i-inherited
|
27
|
+
def self.inherited(base)
|
28
|
+
super
|
29
|
+
|
30
|
+
base.class_eval do
|
31
|
+
include Lotus::Utils::ClassAttribute
|
22
32
|
|
23
|
-
|
33
|
+
class_attribute :configuration
|
34
|
+
self.configuration = Configuration.new
|
35
|
+
end
|
36
|
+
|
37
|
+
synchronize do
|
38
|
+
applications.add(base)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
# Registry of Lotus applications in the current Ruby process
|
24
43
|
#
|
25
|
-
# @
|
44
|
+
# @return [Set] a set of all the registered applications
|
45
|
+
#
|
46
|
+
# @since 0.2.0
|
26
47
|
# @api private
|
27
|
-
|
28
|
-
|
48
|
+
def self.applications
|
49
|
+
synchronize do
|
50
|
+
@@applications ||= Set.new
|
51
|
+
end
|
52
|
+
end
|
29
53
|
|
30
54
|
# Configure the application.
|
31
55
|
# It yields the given block in the context of the configuration
|
32
56
|
#
|
57
|
+
# @param environment [Symbol,nil] the configuration environment name
|
33
58
|
# @param blk [Proc] the configuration block
|
34
59
|
#
|
35
60
|
# @since 0.1.0
|
@@ -46,8 +71,8 @@ module Lotus
|
|
46
71
|
# end
|
47
72
|
# end
|
48
73
|
# end
|
49
|
-
def self.configure(&blk)
|
50
|
-
configuration.configure(&blk)
|
74
|
+
def self.configure(environment = nil, &blk)
|
75
|
+
configuration.configure(environment, &blk)
|
51
76
|
end
|
52
77
|
|
53
78
|
# Return the routes for this application
|
@@ -67,16 +92,68 @@ module Lotus
|
|
67
92
|
# @api private
|
68
93
|
attr_writer :routes
|
69
94
|
|
95
|
+
# Rendering policy
|
96
|
+
#
|
97
|
+
# @param [Lotus::RenderingPolicy]
|
98
|
+
#
|
99
|
+
# @since 0.2.0
|
100
|
+
# @api private
|
101
|
+
attr_accessor :renderer
|
102
|
+
|
70
103
|
# Initialize and load a new instance of the application
|
71
104
|
#
|
72
105
|
# @return [Lotus::Application] a new instance of the application
|
73
106
|
#
|
74
107
|
# @since 0.1.0
|
75
108
|
def initialize
|
76
|
-
|
77
|
-
|
109
|
+
self.class.load!(self)
|
110
|
+
end
|
78
111
|
|
79
|
-
|
112
|
+
# Eager load the application configuration, by activating the framework
|
113
|
+
# duplication mechanisms.
|
114
|
+
#
|
115
|
+
# @param application [Lotus::Application, Class<Lotus::Application>]
|
116
|
+
# @return void
|
117
|
+
#
|
118
|
+
# @since 0.1.1
|
119
|
+
#
|
120
|
+
# @example
|
121
|
+
# require 'lotus'
|
122
|
+
#
|
123
|
+
# module OneFile
|
124
|
+
# class Application < Lotus::Application
|
125
|
+
# configure do
|
126
|
+
# routes do
|
127
|
+
# get '/', to: 'dashboard#index'
|
128
|
+
# end
|
129
|
+
# end
|
130
|
+
#
|
131
|
+
# load!
|
132
|
+
# end
|
133
|
+
#
|
134
|
+
# module Controllers::Dashboard
|
135
|
+
# include OneFile::Controller
|
136
|
+
#
|
137
|
+
# action 'Index' do
|
138
|
+
# def call(params)
|
139
|
+
# self.body = 'Hello!'
|
140
|
+
# end
|
141
|
+
# end
|
142
|
+
# end
|
143
|
+
# end
|
144
|
+
def self.load!(application = self)
|
145
|
+
Lotus::Loader.new(application).load!
|
146
|
+
end
|
147
|
+
|
148
|
+
# Preload all the registered applications
|
149
|
+
#
|
150
|
+
# @return [void]
|
151
|
+
#
|
152
|
+
# @since 0.2.0
|
153
|
+
def self.preload!
|
154
|
+
synchronize do
|
155
|
+
applications.each(&:load!)
|
156
|
+
end
|
80
157
|
end
|
81
158
|
|
82
159
|
# Return the configuration for this application
|
@@ -89,6 +166,14 @@ module Lotus
|
|
89
166
|
self.class.configuration
|
90
167
|
end
|
91
168
|
|
169
|
+
# Return the application name
|
170
|
+
#
|
171
|
+
# @since 0.2.0
|
172
|
+
# @api private
|
173
|
+
def name
|
174
|
+
self.class.name
|
175
|
+
end
|
176
|
+
|
92
177
|
# Process a request.
|
93
178
|
# This method makes Lotus applications compatible with the Rack protocol.
|
94
179
|
#
|
@@ -101,9 +186,8 @@ module Lotus
|
|
101
186
|
# @see http://rack.github.io
|
102
187
|
# @see Lotus::Application#middleware
|
103
188
|
def call(env)
|
104
|
-
|
105
|
-
|
106
|
-
end
|
189
|
+
renderer.render(env,
|
190
|
+
middleware.call(env))
|
107
191
|
end
|
108
192
|
|
109
193
|
# Rack middleware stack
|
@@ -115,7 +199,19 @@ module Lotus
|
|
115
199
|
#
|
116
200
|
# @see Lotus::Middleware
|
117
201
|
def middleware
|
118
|
-
@middleware ||=
|
202
|
+
@middleware ||= configuration.middleware
|
203
|
+
end
|
204
|
+
|
205
|
+
private
|
206
|
+
|
207
|
+
# Yields the given block in a critical section
|
208
|
+
#
|
209
|
+
# @since 0.2.0
|
210
|
+
# @api private
|
211
|
+
def self.synchronize
|
212
|
+
Mutex.new.synchronize do
|
213
|
+
yield
|
214
|
+
end
|
119
215
|
end
|
120
216
|
end
|
121
217
|
end
|
data/lib/lotus/cli.rb
ADDED
@@ -0,0 +1,85 @@
|
|
1
|
+
require 'thor'
|
2
|
+
require 'lotus/environment'
|
3
|
+
require 'lotus/version'
|
4
|
+
|
5
|
+
module Lotus
|
6
|
+
class Cli < Thor
|
7
|
+
include Thor::Actions
|
8
|
+
|
9
|
+
desc 'version', 'prints Lotus version'
|
10
|
+
def version
|
11
|
+
puts Lotus::VERSION
|
12
|
+
end
|
13
|
+
|
14
|
+
desc 'server', 'starts a lotus server'
|
15
|
+
method_option :port, aliases: '-p', desc: 'The port to run the server on, '
|
16
|
+
method_option :server, desc: 'choose a specific Rack::Handler, e.g. webrick, thin etc'
|
17
|
+
method_option :rackup, desc: 'a rackup configuration file path to load (config.ru)'
|
18
|
+
method_option :host, desc: 'the host address to bind to'
|
19
|
+
method_option :debug, desc: 'turn on debug output'
|
20
|
+
method_option :warn, desc: 'turn on warnings'
|
21
|
+
method_option :daemonize, desc: 'if true, the server will daemonize itself (fork, detach, etc)'
|
22
|
+
method_option :pid, desc: 'path to write a pid file after daemonize'
|
23
|
+
method_option :environment, desc: 'path to environment configuration (config/environment.rb)'
|
24
|
+
method_option :code_reloading, desc: 'code reloading', type: :boolean, default: true
|
25
|
+
method_option :help, aliases: '-h', desc: 'displays the usage message'
|
26
|
+
|
27
|
+
def server
|
28
|
+
if options[:help]
|
29
|
+
invoke :help, ['server']
|
30
|
+
else
|
31
|
+
require 'lotus/commands/server'
|
32
|
+
Lotus::Commands::Server.new(environment).start
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
desc 'console', 'starts a lotus console'
|
37
|
+
method_option :environment, desc: 'path to environment configuration (config/environment.rb)'
|
38
|
+
method_option :engine, desc: 'choose a specific console engine: irb/pry/ripl (irb)'
|
39
|
+
method_option :help, aliases: '-h', desc: 'displays the usage method'
|
40
|
+
|
41
|
+
def console
|
42
|
+
if options[:help]
|
43
|
+
invoke :help, ['console']
|
44
|
+
else
|
45
|
+
require 'lotus/commands/console'
|
46
|
+
Lotus::Commands::Console.new(environment).start
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
desc 'routes', 'prints routes'
|
51
|
+
method_option :environment, desc: 'path to environment configuration (config/environment.rb)'
|
52
|
+
method_option :help, aliases: '-h', desc: 'displays the usage method'
|
53
|
+
|
54
|
+
def routes
|
55
|
+
if options[:help]
|
56
|
+
invoke :help, ['routes']
|
57
|
+
else
|
58
|
+
require 'lotus/commands/routes'
|
59
|
+
Lotus::Commands::Routes.new(environment).start
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
desc 'new', 'generates a new application'
|
64
|
+
method_option :architecture, aliases: '-a', desc: 'application architecture', type: :string, default: 'container'
|
65
|
+
method_option :application, desc: 'application name', type: :string, default: 'web'
|
66
|
+
method_option :application_base_url, desc: 'application base url', type: :string, default: '/'
|
67
|
+
method_option :lotus_head, desc: 'use Lotus HEAD', type: :boolean, default: false
|
68
|
+
method_option :help, aliases: '-h', desc: 'displays the usage method'
|
69
|
+
|
70
|
+
def new(name = nil)
|
71
|
+
if options[:help]
|
72
|
+
invoke :help, ['new']
|
73
|
+
else
|
74
|
+
require 'lotus/commands/new'
|
75
|
+
Lotus::Commands::New.new(name, environment, self).start
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
private
|
80
|
+
|
81
|
+
def environment
|
82
|
+
Lotus::Environment.new(options)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
module Lotus
|
2
|
+
module Commands
|
3
|
+
class Console
|
4
|
+
module Methods
|
5
|
+
def reload!
|
6
|
+
puts 'Reloading...'
|
7
|
+
Kernel.exec "#{$0} console"
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
ENGINES = {
|
12
|
+
'pry' => 'Pry',
|
13
|
+
'ripl' => 'Ripl',
|
14
|
+
'irb' => 'IRB'
|
15
|
+
}.freeze
|
16
|
+
|
17
|
+
attr_reader :options
|
18
|
+
|
19
|
+
def initialize(environment)
|
20
|
+
@environment = environment
|
21
|
+
@options = environment.to_options
|
22
|
+
end
|
23
|
+
|
24
|
+
def start
|
25
|
+
# Clear out ARGV so Pry/IRB don't attempt to parse the rest
|
26
|
+
ARGV.shift until ARGV.empty?
|
27
|
+
require @environment.env_config.to_s
|
28
|
+
|
29
|
+
# Add convenience methods to the main:Object binding
|
30
|
+
TOPLEVEL_BINDING.eval('self').send(:include, Methods)
|
31
|
+
Lotus::Application.preload!
|
32
|
+
|
33
|
+
engine.start
|
34
|
+
end
|
35
|
+
|
36
|
+
def engine
|
37
|
+
load_engine options.fetch(:engine) { engine_lookup }
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
def engine_lookup
|
43
|
+
(ENGINES.find { |_, klass| Object.const_defined?(klass) } || default_engine).first
|
44
|
+
end
|
45
|
+
|
46
|
+
def default_engine
|
47
|
+
ENGINES.to_a.last
|
48
|
+
end
|
49
|
+
|
50
|
+
def load_engine(engine)
|
51
|
+
require engine
|
52
|
+
rescue LoadError
|
53
|
+
ensure
|
54
|
+
return Object.const_get(
|
55
|
+
ENGINES.fetch(engine) {
|
56
|
+
raise ArgumentError.new("Unknown console engine: #{ engine }")
|
57
|
+
}
|
58
|
+
)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'pathname'
|
2
|
+
require 'lotus/utils/string'
|
3
|
+
require 'lotus/utils/class'
|
4
|
+
|
5
|
+
module Lotus
|
6
|
+
module Commands
|
7
|
+
class New
|
8
|
+
GENERATORS_NAMESPACE = "Lotus::Generators::Application::%s".freeze
|
9
|
+
|
10
|
+
attr_reader :app_name, :source, :target, :cli, :options
|
11
|
+
|
12
|
+
def initialize(app_name, environment, cli)
|
13
|
+
@app_name = app_name
|
14
|
+
@options = environment.to_options
|
15
|
+
@arch = @options.fetch(:architecture)
|
16
|
+
|
17
|
+
@target = Pathname.pwd.join(@app_name)
|
18
|
+
@source = Pathname.new(@options.fetch(:source) { ::File.dirname(__FILE__) + '/../generators/application/' }).join(@arch)
|
19
|
+
|
20
|
+
@cli = cli
|
21
|
+
|
22
|
+
require "lotus/generators/application/#{ @arch }"
|
23
|
+
command = Utils::String.new(@arch).classify
|
24
|
+
@command = Utils::Class.load!(GENERATORS_NAMESPACE % command).new(self)
|
25
|
+
end
|
26
|
+
|
27
|
+
def start
|
28
|
+
@command.start
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
require 'rack'
|
2
|
+
|
3
|
+
module Lotus
|
4
|
+
module Commands
|
5
|
+
# Rack compatible server.
|
6
|
+
#
|
7
|
+
# It is run with:
|
8
|
+
#
|
9
|
+
# `bundle exec lotus server`
|
10
|
+
#
|
11
|
+
# It runs the application, by using the server specified in your `Gemfile`
|
12
|
+
# (eg. Puma or Unicorn).
|
13
|
+
#
|
14
|
+
# It enables code reloading by default.
|
15
|
+
# This feature is implemented via process fork and requires `shotgun` gem.
|
16
|
+
#
|
17
|
+
# @since 0.1.0
|
18
|
+
# @api private
|
19
|
+
class Server < ::Rack::Server
|
20
|
+
attr_reader :options
|
21
|
+
|
22
|
+
def initialize(env)
|
23
|
+
@_env = env
|
24
|
+
@options = _extract_options(@_env)
|
25
|
+
|
26
|
+
if code_reloading?
|
27
|
+
require 'shotgun'
|
28
|
+
@app = Shotgun::Loader.new(@_env.rackup.to_s)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
# Primarily this removes the ::Rack::Chunked middleware
|
33
|
+
# which is the cause of Safari content-length bugs.
|
34
|
+
def middleware
|
35
|
+
mw = Hash.new { |e, m| e[m] = [] }
|
36
|
+
mw["deployment"].concat([::Rack::ContentLength, ::Rack::CommonLogger])
|
37
|
+
mw["development"].concat(mw["deployment"] + [::Rack::ShowExceptions, ::Rack::Lint])
|
38
|
+
mw
|
39
|
+
end
|
40
|
+
|
41
|
+
def start
|
42
|
+
if code_reloading?
|
43
|
+
Shotgun.enable_copy_on_write
|
44
|
+
Shotgun.preload
|
45
|
+
end
|
46
|
+
|
47
|
+
super
|
48
|
+
end
|
49
|
+
|
50
|
+
private
|
51
|
+
def _extract_options(env)
|
52
|
+
env.to_options.merge(
|
53
|
+
config: env.rackup.to_s,
|
54
|
+
Host: env.host,
|
55
|
+
Port: env.port,
|
56
|
+
AccessLog: []
|
57
|
+
)
|
58
|
+
end
|
59
|
+
|
60
|
+
def code_reloading?
|
61
|
+
@_env.code_reloading?
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
data/lib/lotus/config/assets.rb
CHANGED
@@ -4,26 +4,40 @@ module Lotus
|
|
4
4
|
#
|
5
5
|
# @since 0.1.0
|
6
6
|
# @api private
|
7
|
-
class Assets
|
7
|
+
class Assets < Utils::LoadPaths
|
8
8
|
DEFAULT_DIRECTORY = 'public'.freeze
|
9
9
|
|
10
|
-
|
11
|
-
|
10
|
+
# @since 0.1.0
|
11
|
+
# @api private
|
12
|
+
def initialize(root)
|
13
|
+
@root = root
|
14
|
+
@paths = Array(DEFAULT_DIRECTORY)
|
12
15
|
end
|
13
16
|
|
17
|
+
# @since 0.1.0
|
18
|
+
# @api private
|
14
19
|
def entries
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
20
|
+
hash = Hash.new { |k, v| k[v] = [] }
|
21
|
+
each do |path|
|
22
|
+
if path.exist?
|
23
|
+
hash[path.to_s] = path.children.map { |child| "/#{ child.basename }" }
|
24
|
+
end
|
19
25
|
end
|
26
|
+
hash
|
20
27
|
end
|
21
28
|
|
22
|
-
|
23
|
-
|
29
|
+
# @since 0.2.0
|
30
|
+
# @api private
|
31
|
+
def any?
|
32
|
+
@paths.any?
|
24
33
|
end
|
25
34
|
|
26
|
-
|
35
|
+
protected
|
36
|
+
# @since 0.1.0
|
37
|
+
# @api private
|
38
|
+
def realpath(path)
|
39
|
+
@root.join(path).realpath
|
40
|
+
end
|
27
41
|
end
|
28
42
|
end
|
29
43
|
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'lotus/config/mapper'
|
2
|
+
|
3
|
+
module Lotus
|
4
|
+
module Config
|
5
|
+
# Define configuration of application of
|
6
|
+
# a specific environment
|
7
|
+
#
|
8
|
+
# @since 0.2.0
|
9
|
+
# @api private
|
10
|
+
class Configure < Mapper
|
11
|
+
private
|
12
|
+
def error_message
|
13
|
+
'You must specify a block or a file for configuration definition'
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Lotus
|
2
|
+
module Config
|
3
|
+
# Collects all the settings for a given framework configuration and then
|
4
|
+
# forwards them when the application is loaded.
|
5
|
+
#
|
6
|
+
# @since 0.2.0
|
7
|
+
# @api private
|
8
|
+
class FrameworkConfiguration < BasicObject
|
9
|
+
# @since 0.2.0
|
10
|
+
# @api private
|
11
|
+
def initialize
|
12
|
+
@settings = []
|
13
|
+
end
|
14
|
+
|
15
|
+
# @since 0.2.0
|
16
|
+
# @api private
|
17
|
+
def __apply(configuration)
|
18
|
+
@settings.each do |(m, args, blk)|
|
19
|
+
configuration.public_send(m, *args, &blk)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
# @since 0.2.0
|
24
|
+
# @api private
|
25
|
+
def method_missing(m, *args, &blk)
|
26
|
+
@settings.push([m, args, blk])
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,97 @@
|
|
1
|
+
require 'ipaddr'
|
2
|
+
require 'lotus/utils/string'
|
3
|
+
|
4
|
+
module Lotus
|
5
|
+
module Config
|
6
|
+
# Sessions configuration
|
7
|
+
#
|
8
|
+
# @since 0.2.0
|
9
|
+
# @api private
|
10
|
+
class Sessions
|
11
|
+
|
12
|
+
# Ruby namespace for Rack session adapters
|
13
|
+
#
|
14
|
+
# @since 0.2.0
|
15
|
+
# @api private
|
16
|
+
RACK_NAMESPACE = 'Rack::Session::%s'.freeze
|
17
|
+
|
18
|
+
# Localhost string for detecting localhost host configuration
|
19
|
+
#
|
20
|
+
# @since x.x.x
|
21
|
+
# @api private
|
22
|
+
BLACKLISTED_DOMAINS = %w(localhost).freeze
|
23
|
+
|
24
|
+
# HTTP sessions configuration
|
25
|
+
#
|
26
|
+
# @param adapter [Symbol,String,Class] the session adapter
|
27
|
+
# @param options [Hash] the optional session options
|
28
|
+
# @param configuration [Lotus::Configuration] the application configuration
|
29
|
+
#
|
30
|
+
# @since 0.2.0
|
31
|
+
# @api private
|
32
|
+
#
|
33
|
+
# @see http://www.rubydoc.info/github/rack/rack/Rack/Session/Abstract/ID
|
34
|
+
def initialize(adapter = nil, options = {}, configuration = nil)
|
35
|
+
@adapter = adapter
|
36
|
+
@options = options
|
37
|
+
@configuration = configuration
|
38
|
+
end
|
39
|
+
|
40
|
+
# Check if the sessions are enabled
|
41
|
+
#
|
42
|
+
# @return [FalseClass,TrueClass] the result of the check
|
43
|
+
#
|
44
|
+
# @since 0.2.0
|
45
|
+
# @api private
|
46
|
+
def enabled?
|
47
|
+
!!@adapter
|
48
|
+
end
|
49
|
+
|
50
|
+
# Returns the Rack middleware and the options
|
51
|
+
#
|
52
|
+
# @return [Array] Rack middleware and options
|
53
|
+
#
|
54
|
+
# @since 0.2.0
|
55
|
+
# @api private
|
56
|
+
def middleware
|
57
|
+
middleware = case @adapter
|
58
|
+
when Symbol
|
59
|
+
RACK_NAMESPACE % Utils::String.new(@adapter).classify
|
60
|
+
else
|
61
|
+
@adapter
|
62
|
+
end
|
63
|
+
|
64
|
+
[middleware, options]
|
65
|
+
end
|
66
|
+
|
67
|
+
private
|
68
|
+
|
69
|
+
# @since 0.2.0
|
70
|
+
# @api private
|
71
|
+
def options
|
72
|
+
default_options.merge(@options)
|
73
|
+
end
|
74
|
+
|
75
|
+
# @since 0.2.0
|
76
|
+
# @api private
|
77
|
+
def default_options
|
78
|
+
if @configuration
|
79
|
+
{ domain: domain, secure: @configuration.ssl? }
|
80
|
+
else
|
81
|
+
{}
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def domain
|
86
|
+
domain = @configuration.host
|
87
|
+
if !BLACKLISTED_DOMAINS.include?(domain) && !ip_address?(domain)
|
88
|
+
domain
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
def ip_address?(string)
|
93
|
+
!!IPAddr.new(string) rescue false
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|