hanami 1.3.5 → 2.0.0.alpha1

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.
Files changed (147) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +51 -41
  3. data/FEATURES.md +2 -12
  4. data/LICENSE.md +1 -1
  5. data/README.md +5 -8
  6. data/bin/hanami +6 -4
  7. data/hanami.gemspec +24 -28
  8. data/lib/hanami/application.rb +44 -176
  9. data/lib/hanami/boot.rb +6 -0
  10. data/lib/hanami/cli/commands/command.rb +21 -29
  11. data/lib/hanami/cli/commands/server.rb +63 -14
  12. data/lib/hanami/cli/commands.rb +5 -42
  13. data/lib/hanami/configuration/cookies.rb +24 -0
  14. data/lib/hanami/configuration/middleware.rb +8 -28
  15. data/lib/hanami/configuration/security.rb +141 -0
  16. data/lib/hanami/configuration/sessions.rb +50 -0
  17. data/lib/hanami/configuration.rb +181 -191
  18. data/lib/hanami/container.rb +107 -0
  19. data/lib/hanami/frameworks.rb +24 -18
  20. data/lib/hanami/routes.rb +17 -205
  21. data/lib/hanami/server.rb +5 -69
  22. data/lib/hanami/version.rb +3 -1
  23. data/lib/hanami.rb +39 -243
  24. metadata +36 -233
  25. data/lib/hanami/action/csrf_protection.rb +0 -211
  26. data/lib/hanami/action/routing_helpers.rb +0 -40
  27. data/lib/hanami/app.rb +0 -96
  28. data/lib/hanami/application_configuration.rb +0 -1495
  29. data/lib/hanami/application_name.rb +0 -108
  30. data/lib/hanami/application_namespace.rb +0 -14
  31. data/lib/hanami/assets/asset.rb +0 -72
  32. data/lib/hanami/assets/static.rb +0 -102
  33. data/lib/hanami/cli/commands/assets/precompile.rb +0 -42
  34. data/lib/hanami/cli/commands/assets.rb +0 -16
  35. data/lib/hanami/cli/commands/console.rb +0 -95
  36. data/lib/hanami/cli/commands/db/apply.rb +0 -32
  37. data/lib/hanami/cli/commands/db/console.rb +0 -44
  38. data/lib/hanami/cli/commands/db/create.rb +0 -32
  39. data/lib/hanami/cli/commands/db/drop.rb +0 -32
  40. data/lib/hanami/cli/commands/db/migrate.rb +0 -39
  41. data/lib/hanami/cli/commands/db/prepare.rb +0 -32
  42. data/lib/hanami/cli/commands/db/rollback.rb +0 -59
  43. data/lib/hanami/cli/commands/db/version.rb +0 -32
  44. data/lib/hanami/cli/commands/db.rb +0 -32
  45. data/lib/hanami/cli/commands/destroy/action.rb +0 -137
  46. data/lib/hanami/cli/commands/destroy/app.rb +0 -159
  47. data/lib/hanami/cli/commands/destroy/mailer.rb +0 -74
  48. data/lib/hanami/cli/commands/destroy/migration.rb +0 -51
  49. data/lib/hanami/cli/commands/destroy/model.rb +0 -84
  50. data/lib/hanami/cli/commands/destroy.rb +0 -26
  51. data/lib/hanami/cli/commands/generate/action/action.erb +0 -7
  52. data/lib/hanami/cli/commands/generate/action/action_spec.minitest.erb +0 -11
  53. data/lib/hanami/cli/commands/generate/action/action_spec.rspec.erb +0 -9
  54. data/lib/hanami/cli/commands/generate/action/action_without_view.erb +0 -7
  55. data/lib/hanami/cli/commands/generate/action/view.erb +0 -7
  56. data/lib/hanami/cli/commands/generate/action/view_spec.minitest.erb +0 -12
  57. data/lib/hanami/cli/commands/generate/action/view_spec.rspec.erb +0 -10
  58. data/lib/hanami/cli/commands/generate/action.rb +0 -321
  59. data/lib/hanami/cli/commands/generate/app/application.erb +0 -313
  60. data/lib/hanami/cli/commands/generate/app/favicon.ico +0 -0
  61. data/lib/hanami/cli/commands/generate/app/gitkeep.erb +0 -0
  62. data/lib/hanami/cli/commands/generate/app/layout.erb +0 -7
  63. data/lib/hanami/cli/commands/generate/app/layout_spec.minitest.erb +0 -10
  64. data/lib/hanami/cli/commands/generate/app/layout_spec.rspec.erb +0 -10
  65. data/lib/hanami/cli/commands/generate/app/routes.erb +0 -5
  66. data/lib/hanami/cli/commands/generate/app/template.erb.erb +0 -10
  67. data/lib/hanami/cli/commands/generate/app/template.haml.erb +0 -7
  68. data/lib/hanami/cli/commands/generate/app/template.slim.erb +0 -8
  69. data/lib/hanami/cli/commands/generate/app.rb +0 -243
  70. data/lib/hanami/cli/commands/generate/mailer/mailer.erb +0 -9
  71. data/lib/hanami/cli/commands/generate/mailer/mailer_spec.minitest.erb +0 -7
  72. data/lib/hanami/cli/commands/generate/mailer/mailer_spec.rspec.erb +0 -5
  73. data/lib/hanami/cli/commands/generate/mailer.rb +0 -104
  74. data/lib/hanami/cli/commands/generate/migration/migration.erb +0 -4
  75. data/lib/hanami/cli/commands/generate/migration.rb +0 -41
  76. data/lib/hanami/cli/commands/generate/model/entity.erb +0 -2
  77. data/lib/hanami/cli/commands/generate/model/entity_spec.minitest.erb +0 -5
  78. data/lib/hanami/cli/commands/generate/model/entity_spec.rspec.erb +0 -3
  79. data/lib/hanami/cli/commands/generate/model/migration.erb +0 -10
  80. data/lib/hanami/cli/commands/generate/model/repository.erb +0 -5
  81. data/lib/hanami/cli/commands/generate/model/repository_spec.minitest.erb +0 -5
  82. data/lib/hanami/cli/commands/generate/model/repository_spec.rspec.erb +0 -3
  83. data/lib/hanami/cli/commands/generate/model.rb +0 -125
  84. data/lib/hanami/cli/commands/generate/secret.rb +0 -48
  85. data/lib/hanami/cli/commands/generate.rb +0 -28
  86. data/lib/hanami/cli/commands/new/.env.development.erb +0 -3
  87. data/lib/hanami/cli/commands/new/.env.test.erb +0 -3
  88. data/lib/hanami/cli/commands/new/.gitkeep.erb +0 -0
  89. data/lib/hanami/cli/commands/new/Gemfile.erb +0 -57
  90. data/lib/hanami/cli/commands/new/README.md.erb +0 -33
  91. data/lib/hanami/cli/commands/new/config/boot.erb +0 -2
  92. data/lib/hanami/cli/commands/new/config/environment.erb +0 -49
  93. data/lib/hanami/cli/commands/new/config.ru.erb +0 -3
  94. data/lib/hanami/cli/commands/new/gitignore.erb +0 -4
  95. data/lib/hanami/cli/commands/new/gitignore_with_sqlite.erb +0 -5
  96. data/lib/hanami/cli/commands/new/hanamirc.erb +0 -3
  97. data/lib/hanami/cli/commands/new/lib/project.erb +0 -2
  98. data/lib/hanami/cli/commands/new/minitest/Rakefile.erb +0 -12
  99. data/lib/hanami/cli/commands/new/minitest/features_helper.erb +0 -11
  100. data/lib/hanami/cli/commands/new/minitest/spec_helper.erb +0 -7
  101. data/lib/hanami/cli/commands/new/rspec/Rakefile.erb +0 -9
  102. data/lib/hanami/cli/commands/new/rspec/capybara.erb +0 -8
  103. data/lib/hanami/cli/commands/new/rspec/features_helper.erb +0 -12
  104. data/lib/hanami/cli/commands/new/rspec/rspec.erb +0 -2
  105. data/lib/hanami/cli/commands/new/rspec/spec_helper.erb +0 -103
  106. data/lib/hanami/cli/commands/new/schema.sql.erb +0 -0
  107. data/lib/hanami/cli/commands/new.rb +0 -578
  108. data/lib/hanami/cli/commands/project.rb +0 -421
  109. data/lib/hanami/cli/commands/routes.rb +0 -21
  110. data/lib/hanami/cli/commands/templates.rb +0 -31
  111. data/lib/hanami/cli/commands/version.rb +0 -19
  112. data/lib/hanami/common_logger.rb +0 -109
  113. data/lib/hanami/components/app/assets.rb +0 -59
  114. data/lib/hanami/components/app/controller.rb +0 -74
  115. data/lib/hanami/components/app/routes.rb +0 -59
  116. data/lib/hanami/components/app/view.rb +0 -44
  117. data/lib/hanami/components/component.rb +0 -182
  118. data/lib/hanami/components/components.rb +0 -479
  119. data/lib/hanami/components/routes_inspector.rb +0 -72
  120. data/lib/hanami/components.rb +0 -156
  121. data/lib/hanami/config/cookies.rb +0 -69
  122. data/lib/hanami/config/framework_configuration.rb +0 -43
  123. data/lib/hanami/config/load_paths.rb +0 -46
  124. data/lib/hanami/config/mapper.rb +0 -47
  125. data/lib/hanami/config/routes.rb +0 -20
  126. data/lib/hanami/config/security.rb +0 -110
  127. data/lib/hanami/config/sessions.rb +0 -119
  128. data/lib/hanami/configuration/app.rb +0 -21
  129. data/lib/hanami/early_hints.rb +0 -129
  130. data/lib/hanami/env.rb +0 -69
  131. data/lib/hanami/environment.rb +0 -541
  132. data/lib/hanami/environment_application_configurations.rb +0 -37
  133. data/lib/hanami/hanamirc.rb +0 -169
  134. data/lib/hanami/mailer/glue.rb +0 -27
  135. data/lib/hanami/middleware_stack.rb +0 -172
  136. data/lib/hanami/rake_helper.rb +0 -78
  137. data/lib/hanami/rake_tasks.rb +0 -3
  138. data/lib/hanami/rendering_policy.rb +0 -94
  139. data/lib/hanami/routing/default.rb +0 -32
  140. data/lib/hanami/setup.rb +0 -3
  141. data/lib/hanami/static.rb +0 -63
  142. data/lib/hanami/templates/default.html.erb +0 -30
  143. data/lib/hanami/templates/welcome.html.erb +0 -52
  144. data/lib/hanami/views/default.rb +0 -37
  145. data/lib/hanami/views/default_template_finder.rb +0 -22
  146. data/lib/hanami/views/null_view.rb +0 -15
  147. data/lib/hanami/welcome.rb +0 -41
@@ -1,35 +1,84 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Hanami
4
+ # Hanami CLI
5
+ #
6
+ # @since 1.1.0
2
7
  class CLI
3
8
  module Commands
4
9
  # @since 1.1.0
5
10
  # @api private
6
11
  class Server < Command
7
- requires 'code_reloading'
8
-
9
12
  desc "Start Hanami server (only for development)"
10
13
 
11
- option :server, desc: "Force a server engine (eg, webrick, puma, thin, etc..)"
12
- option :host, desc: "The host address to bind to"
13
- option :port, desc: "The port to run the server on", aliases: ["-p"]
14
- option :debug, desc: "Turn on debug output"
15
- option :warn, desc: "Turn on warnings"
16
- option :daemonize, desc: "Daemonize the server"
17
- option :pid, desc: "Path to write a pid file after daemonize"
18
- option :code_reloading, desc: "Code reloading", type: :boolean, default: true
14
+ option :server, desc: "Force a server engine (eg, webrick, puma, thin, etc..)"
15
+ option :host, desc: "The host address to bind to"
16
+ option :port, desc: "The port to run the server on", aliases: ["-p"]
17
+ option :debug, desc: "Turn on debug output", type: :boolean
18
+ option :warn, desc: "Turn on warnings", type: :boolean
19
+ option :daemonize, desc: "Daemonize the server", type: :boolean
20
+ option :pid, desc: "Path to write a pid file after daemonize"
19
21
 
20
22
  example [
21
23
  " # Basic usage (it uses the bundled server engine)",
22
24
  "--server=webrick # Force `webrick` server engine",
23
25
  "--host=0.0.0.0 # Bind to a host",
24
- "--port=2306 # Bind to a port",
25
- "--no-code-reloading # Disable code reloading"
26
+ "--port=2306 # Bind to a port"
26
27
  ]
27
28
 
28
29
  # @since 1.1.0
29
30
  # @api private
30
- def call(*)
31
+ def call(**args)
32
+ require "hanami"
33
+ require "hanami/container"
31
34
  require "hanami/server"
32
- Hanami::Server.new.start
35
+
36
+ options = parse_arguments(args)
37
+ Hanami::Server.new(options).start
38
+ end
39
+
40
+ private
41
+
42
+ DEFAULT_CONFIG = "config.ru"
43
+ private_constant :DEFAULT_CONFIG
44
+
45
+ DEFAULT_HOST = "0.0.0.0"
46
+ private_constant :DEFAULT_HOST
47
+
48
+ DEFAULT_PORT = "2300"
49
+ private_constant :DEFAULT_PORT
50
+
51
+ OPTIONAL_SETTINGS = %i[
52
+ server
53
+ debug
54
+ warn
55
+ daemonize
56
+ pid
57
+ ].freeze
58
+
59
+ def parse_arguments(args)
60
+ Hanami::Container.start(:env)
61
+
62
+ {
63
+ config: DEFAULT_CONFIG,
64
+ Host: host(args),
65
+ Port: port(args),
66
+ AccessLog: []
67
+ }.merge(
68
+ args.slice(*OPTIONAL_SETTINGS)
69
+ )
70
+ end
71
+
72
+ def host(args)
73
+ args.fetch(:host) do
74
+ ENV.fetch("HANAMI_HOST", DEFAULT_HOST)
75
+ end
76
+ end
77
+
78
+ def port(args)
79
+ args.fetch(:port) do
80
+ ENV.fetch("HANAMI_PORT", DEFAULT_PORT)
81
+ end
33
82
  end
34
83
  end
35
84
  end
@@ -1,5 +1,6 @@
1
- require 'dry/cli'
2
- require 'ostruct'
1
+ # frozen_string_literal: true
2
+
3
+ require "hanami/cli"
3
4
 
4
5
  module Hanami
5
6
  # Hanami CLI
@@ -23,7 +24,7 @@ module Hanami
23
24
  # module CLI
24
25
  # module Commands
25
26
  # class Generate < Hanami::CLI::Command
26
- # desc "Generate Webpack config"
27
+ # desc "Generate Webpack configuration"
27
28
  #
28
29
  # def call(*)
29
30
  # # ...
@@ -54,48 +55,10 @@ module Hanami
54
55
  # @since 1.1.0
55
56
  # @api private
56
57
  module Commands
57
- extend Dry::CLI::Registry
58
-
59
- # CLI command context
60
- #
61
- # @since 1.1.0
62
- # @api private
63
- class Context < OpenStruct
64
- # @since 1.1.0
65
- # @api private
66
- def initialize(data)
67
- data = data.each_with_object({}) do |(k, v), result|
68
- v = Utils::String.new(v) if v.is_a?(::String)
69
- result[k] = v
70
- end
71
-
72
- super(data)
73
- freeze
74
- end
75
-
76
- # @since 1.1.0
77
- # @api private
78
- def with(data)
79
- self.class.new(to_h.merge(data))
80
- end
81
-
82
- # @since 1.1.0
83
- # @api private
84
- def binding
85
- super
86
- end
87
- end
58
+ extend Hanami::CLI::Registry
88
59
 
89
60
  require "hanami/cli/commands/command"
90
- require "hanami/cli/commands/assets"
91
- require "hanami/cli/commands/console"
92
- require "hanami/cli/commands/db"
93
- require "hanami/cli/commands/destroy"
94
- require "hanami/cli/commands/generate"
95
- require "hanami/cli/commands/new"
96
- require "hanami/cli/commands/routes"
97
61
  require "hanami/cli/commands/server"
98
- require "hanami/cli/commands/version"
99
62
  end
100
63
  end
101
64
  end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Hanami
4
+ class Configuration
5
+ # Hanami configuration for HTTP cookies
6
+ #
7
+ # @since 2.0.0
8
+ class Cookies
9
+ def self.null
10
+ { null: true }
11
+ end
12
+
13
+ attr_reader :options
14
+
15
+ def initialize(options)
16
+ @options = options
17
+ end
18
+
19
+ def enabled?
20
+ options != self.class.null
21
+ end
22
+ end
23
+ end
24
+ end
@@ -1,40 +1,20 @@
1
- require "concurrent"
1
+ # frozen_string_literal: true
2
2
 
3
3
  module Hanami
4
- # @api private
5
4
  class Configuration
6
- # Middleware configuration
7
- # @since 1.2.0
5
+ # Hanami application configured Rack middleware
6
+ #
7
+ # @since 2.0.0
8
8
  class Middleware
9
- # @api private
10
- # @since 1.2.0
11
9
  def initialize
12
- @middleware = Concurrent::Array.new
10
+ @stack = []
13
11
  end
14
12
 
15
- # Use a Rack middleware
16
- #
17
- # @param middleware [#call] a Rack middleware
18
- # @param args [Array<Object>] an optional set of options
19
- # @param blk [Proc] an optional block to pass to the middleware
20
- #
21
- # @since 1.2.0
22
- #
23
- # @example
24
- # # config/environment.rb
25
- # # ...
26
- # Hanami.configure do
27
- # middleware.use MyRackMiddleware
28
- # end
29
- def use(middleware, *args, &blk)
30
- @middleware.push([middleware, args, blk])
13
+ def use(middleware, *args)
14
+ stack.push([middleware, *args])
31
15
  end
32
16
 
33
- # @api private
34
- # @since 1.2.0
35
- def each(&blk)
36
- @middleware.each(&blk)
37
- end
17
+ attr_reader :stack
38
18
  end
39
19
  end
40
20
  end
@@ -0,0 +1,141 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "concurrent/hash"
4
+ require "hanami/utils/string"
5
+
6
+ module Hanami
7
+ class Configuration
8
+ # Hanami configuration security settings
9
+ #
10
+ # @since 2.0.0
11
+ class Security
12
+ def initialize
13
+ @settings = Concurrent::Hash.new
14
+ settings[:x_frame_options] = Setting.new(HEADER_X_FRAME_OPTIONS, DEFAULT_X_FRAME_OPTIONS)
15
+ settings[:x_content_type_options] = Setting.new(HEADER_X_CONTENT_TYPE_OPTIONS, DEFAULT_X_CONTENT_TYPE_OPTIONS)
16
+ settings[:x_xss_protection] = Setting.new(HEADER_X_XSS_PROTECTION, DEFAULT_X_XSS_PROTECTION)
17
+ settings[:content_security_policy] = ContentSecurityPolicy.new(HEADER_CONTENT_SECURITY_POLICY, DEFAULT_CONTENT_SECURITY_POLICY.dup)
18
+ end
19
+
20
+ def x_frame_options=(value)
21
+ settings[:x_frame_options].value = value
22
+ end
23
+
24
+ def x_frame_options
25
+ settings.fetch(:x_frame_options)
26
+ end
27
+
28
+ def x_content_type_options=(value)
29
+ settings[:x_content_type_options].value = value
30
+ end
31
+
32
+ def x_content_type_options
33
+ settings.fetch(:x_content_type_options)
34
+ end
35
+
36
+ def x_xss_protection=(value)
37
+ settings[:x_xss_protection].value = value
38
+ end
39
+
40
+ def x_xss_protection
41
+ settings.fetch(:x_xss_protection)
42
+ end
43
+
44
+ def content_security_policy=(options)
45
+ settings[:content_security_policy].value = options
46
+ end
47
+
48
+ def content_security_policy
49
+ settings.fetch(:content_security_policy)
50
+ end
51
+
52
+ def to_hash
53
+ settings.each_with_object({}) do |(_, v), result|
54
+ next if v.value.nil?
55
+
56
+ result[v.header] = v.value
57
+ end
58
+ end
59
+
60
+ private
61
+
62
+ # X-Frame-Options
63
+ HEADER_X_FRAME_OPTIONS = "X-Frame-Options"
64
+ private_constant :HEADER_X_FRAME_OPTIONS
65
+
66
+ DEFAULT_X_FRAME_OPTIONS = "DENY"
67
+ private_constant :DEFAULT_X_FRAME_OPTIONS
68
+
69
+ # X-Content-Type-Optionx
70
+ HEADER_X_CONTENT_TYPE_OPTIONS = "X-Content-Type-Options"
71
+ private_constant :HEADER_X_CONTENT_TYPE_OPTIONS
72
+
73
+ DEFAULT_X_CONTENT_TYPE_OPTIONS = "nosniff"
74
+ private_constant :DEFAULT_X_CONTENT_TYPE_OPTIONS
75
+
76
+ # X-XSS-Protection
77
+ HEADER_X_XSS_PROTECTION = "X-XSS-Protection"
78
+ private_constant :HEADER_X_XSS_PROTECTION
79
+
80
+ DEFAULT_X_XSS_PROTECTION = "1; mode=block"
81
+ private_constant :DEFAULT_X_XSS_PROTECTION
82
+
83
+ # Content-Security-Policy
84
+ HEADER_CONTENT_SECURITY_POLICY = "Content-Security-Policy"
85
+ private_constant :HEADER_CONTENT_SECURITY_POLICY
86
+
87
+ DEFAULT_CONTENT_SECURITY_POLICY = {
88
+ form_action: "'self'",
89
+ frame_ancestors: "'self'",
90
+ base_uri: "'self'",
91
+ default_src: "'none'",
92
+ script_src: "'self'",
93
+ connect_src: "'self'",
94
+ img_src: "'self' https: data:",
95
+ style_src: "'self' 'unsafe-inline' https:",
96
+ font_src: "'self'",
97
+ object_src: "'none'",
98
+ plugin_types: "application/pdf",
99
+ child_src: "'self'",
100
+ frame_src: "'self'",
101
+ media_src: "'self'"
102
+ }.freeze
103
+ private_constant :DEFAULT_CONTENT_SECURITY_POLICY
104
+
105
+ # Security setting
106
+ #
107
+ # @api private
108
+ # @since 2.0.0
109
+ class Setting
110
+ attr_accessor :header, :value
111
+
112
+ def initialize(header, value)
113
+ @header = header.freeze
114
+ @value = value
115
+ end
116
+ end
117
+
118
+ # Content security policy settings
119
+ #
120
+ # @api private
121
+ # @since 2.0.0
122
+ class ContentSecurityPolicy < Setting
123
+ def value
124
+ @value.map do |k, v|
125
+ "#{Utils::String.dasherize(k)} #{v}" unless v.nil?
126
+ end.compact.join("; ")
127
+ end
128
+
129
+ def [](key)
130
+ @value[key]
131
+ end
132
+
133
+ def []=(key, value)
134
+ @value[key] = value
135
+ end
136
+ end
137
+
138
+ attr_reader :settings
139
+ end
140
+ end
141
+ end
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "hanami/utils/string"
4
+ require "hanami/utils/class"
5
+
6
+ module Hanami
7
+ class Configuration
8
+ # Hanami configuration for HTTP sessions
9
+ #
10
+ # @since 2.0.0
11
+ class Sessions
12
+ def self.null
13
+ NULL_STORAGE
14
+ end
15
+
16
+ attr_reader :storage, :options
17
+
18
+ def initialize(*args)
19
+ storage, options, = Array(args.dup).flatten
20
+
21
+ @storage = storage
22
+ @options = options || {}
23
+ end
24
+
25
+ def enabled?
26
+ storage != NULL_STORAGE
27
+ end
28
+
29
+ def middleware
30
+ [[storage_middleware, options]]
31
+ end
32
+
33
+ private
34
+
35
+ NULL_STORAGE = :null
36
+ private_constant :NULL_STORAGE
37
+
38
+ def storage_middleware
39
+ require_storage
40
+
41
+ name = Utils::String.classify(storage)
42
+ Utils::Class.load!(name, Rack::Session)
43
+ end
44
+
45
+ def require_storage
46
+ require "rack/session/#{storage}"
47
+ end
48
+ end
49
+ end
50
+ end