piko-lite-box 0.0.1

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 (99) hide show
  1. checksums.yaml +7 -0
  2. data/hanami-3.0.1/CHANGELOG.md +1701 -0
  3. data/hanami-3.0.1/LICENSE +20 -0
  4. data/hanami-3.0.1/README.md +89 -0
  5. data/hanami-3.0.1/hanami.gemspec +49 -0
  6. data/hanami-3.0.1/lib/hanami/app.rb +197 -0
  7. data/hanami-3.0.1/lib/hanami/boot.rb +5 -0
  8. data/hanami-3.0.1/lib/hanami/config/actions/content_security_policy.rb +140 -0
  9. data/hanami-3.0.1/lib/hanami/config/actions/cookies.rb +57 -0
  10. data/hanami-3.0.1/lib/hanami/config/actions/sessions.rb +83 -0
  11. data/hanami-3.0.1/lib/hanami/config/actions.rb +189 -0
  12. data/hanami-3.0.1/lib/hanami/config/assets.rb +84 -0
  13. data/hanami-3.0.1/lib/hanami/config/console.rb +79 -0
  14. data/hanami-3.0.1/lib/hanami/config/db.rb +35 -0
  15. data/hanami-3.0.1/lib/hanami/config/i18n.rb +138 -0
  16. data/hanami-3.0.1/lib/hanami/config/logger.rb +207 -0
  17. data/hanami-3.0.1/lib/hanami/config/null_config.rb +17 -0
  18. data/hanami-3.0.1/lib/hanami/config/router.rb +48 -0
  19. data/hanami-3.0.1/lib/hanami/config/views.rb +103 -0
  20. data/hanami-3.0.1/lib/hanami/config.rb +564 -0
  21. data/hanami-3.0.1/lib/hanami/constants.rb +62 -0
  22. data/hanami-3.0.1/lib/hanami/env.rb +52 -0
  23. data/hanami-3.0.1/lib/hanami/errors.rb +41 -0
  24. data/hanami-3.0.1/lib/hanami/extensions/action/i18n_helper.rb +64 -0
  25. data/hanami-3.0.1/lib/hanami/extensions/action/name_inferrer.rb +34 -0
  26. data/hanami-3.0.1/lib/hanami/extensions/action/slice_configured_action.rb +190 -0
  27. data/hanami-3.0.1/lib/hanami/extensions/action.rb +147 -0
  28. data/hanami-3.0.1/lib/hanami/extensions/db/repo.rb +108 -0
  29. data/hanami-3.0.1/lib/hanami/extensions/mailer/slice_configured_mailer.rb +134 -0
  30. data/hanami-3.0.1/lib/hanami/extensions/mailer.rb +28 -0
  31. data/hanami-3.0.1/lib/hanami/extensions/operation/slice_configured_db_operation.rb +90 -0
  32. data/hanami-3.0.1/lib/hanami/extensions/operation.rb +33 -0
  33. data/hanami-3.0.1/lib/hanami/extensions/router/errors.rb +58 -0
  34. data/hanami-3.0.1/lib/hanami/extensions/view/context.rb +298 -0
  35. data/hanami-3.0.1/lib/hanami/extensions/view/part.rb +92 -0
  36. data/hanami-3.0.1/lib/hanami/extensions/view/scope.rb +36 -0
  37. data/hanami-3.0.1/lib/hanami/extensions/view/slice_configured_context.rb +73 -0
  38. data/hanami-3.0.1/lib/hanami/extensions/view/slice_configured_helpers.rb +55 -0
  39. data/hanami-3.0.1/lib/hanami/extensions/view/slice_configured_part.rb +73 -0
  40. data/hanami-3.0.1/lib/hanami/extensions/view/slice_configured_view.rb +243 -0
  41. data/hanami-3.0.1/lib/hanami/extensions/view/standard_helpers.rb +26 -0
  42. data/hanami-3.0.1/lib/hanami/extensions/view.rb +38 -0
  43. data/hanami-3.0.1/lib/hanami/extensions.rb +30 -0
  44. data/hanami-3.0.1/lib/hanami/helpers/assets_helper.rb +804 -0
  45. data/hanami-3.0.1/lib/hanami/helpers/form_helper/form_builder.rb +1389 -0
  46. data/hanami-3.0.1/lib/hanami/helpers/form_helper/values.rb +75 -0
  47. data/hanami-3.0.1/lib/hanami/helpers/form_helper.rb +213 -0
  48. data/hanami-3.0.1/lib/hanami/helpers/i18n_helper.rb +241 -0
  49. data/hanami-3.0.1/lib/hanami/logger/rack_formatter.rb +73 -0
  50. data/hanami-3.0.1/lib/hanami/logger/sql_formatter.rb +80 -0
  51. data/hanami-3.0.1/lib/hanami/logger/sql_logger.rb +48 -0
  52. data/hanami-3.0.1/lib/hanami/middleware/assets.rb +21 -0
  53. data/hanami-3.0.1/lib/hanami/middleware/content_security_policy_nonce.rb +53 -0
  54. data/hanami-3.0.1/lib/hanami/middleware/public_errors_app.rb +75 -0
  55. data/hanami-3.0.1/lib/hanami/middleware/render_errors.rb +90 -0
  56. data/hanami-3.0.1/lib/hanami/port.rb +45 -0
  57. data/hanami-3.0.1/lib/hanami/prepare.rb +5 -0
  58. data/hanami-3.0.1/lib/hanami/provider/source.rb +16 -0
  59. data/hanami-3.0.1/lib/hanami/provider_registrar.rb +28 -0
  60. data/hanami-3.0.1/lib/hanami/providers/assets.rb +28 -0
  61. data/hanami-3.0.1/lib/hanami/providers/db/adapter.rb +75 -0
  62. data/hanami-3.0.1/lib/hanami/providers/db/adapters.rb +66 -0
  63. data/hanami-3.0.1/lib/hanami/providers/db/config.rb +44 -0
  64. data/hanami-3.0.1/lib/hanami/providers/db/gateway.rb +87 -0
  65. data/hanami-3.0.1/lib/hanami/providers/db/sql_adapter.rb +100 -0
  66. data/hanami-3.0.1/lib/hanami/providers/db.rb +325 -0
  67. data/hanami-3.0.1/lib/hanami/providers/db_logging.rb +19 -0
  68. data/hanami-3.0.1/lib/hanami/providers/i18n/backend.rb +373 -0
  69. data/hanami-3.0.1/lib/hanami/providers/i18n/locale/en.yml +57 -0
  70. data/hanami-3.0.1/lib/hanami/providers/i18n.rb +114 -0
  71. data/hanami-3.0.1/lib/hanami/providers/inflector.rb +17 -0
  72. data/hanami-3.0.1/lib/hanami/providers/logger.rb +41 -0
  73. data/hanami-3.0.1/lib/hanami/providers/mailers.rb +101 -0
  74. data/hanami-3.0.1/lib/hanami/providers/rack.rb +47 -0
  75. data/hanami-3.0.1/lib/hanami/providers/relations.rb +31 -0
  76. data/hanami-3.0.1/lib/hanami/providers/routes.rb +29 -0
  77. data/hanami-3.0.1/lib/hanami/rake_tasks.rb +54 -0
  78. data/hanami-3.0.1/lib/hanami/routes.rb +146 -0
  79. data/hanami-3.0.1/lib/hanami/settings/composite_store.rb +53 -0
  80. data/hanami-3.0.1/lib/hanami/settings/env_store.rb +32 -0
  81. data/hanami-3.0.1/lib/hanami/settings.rb +234 -0
  82. data/hanami-3.0.1/lib/hanami/setup.rb +6 -0
  83. data/hanami-3.0.1/lib/hanami/slice/router.rb +280 -0
  84. data/hanami-3.0.1/lib/hanami/slice/routes_helper.rb +37 -0
  85. data/hanami-3.0.1/lib/hanami/slice/routing/middleware/stack.rb +216 -0
  86. data/hanami-3.0.1/lib/hanami/slice/routing/resolver.rb +88 -0
  87. data/hanami-3.0.1/lib/hanami/slice/view_name_inferrer.rb +63 -0
  88. data/hanami-3.0.1/lib/hanami/slice.rb +1239 -0
  89. data/hanami-3.0.1/lib/hanami/slice_configurable.rb +72 -0
  90. data/hanami-3.0.1/lib/hanami/slice_name.rb +111 -0
  91. data/hanami-3.0.1/lib/hanami/slice_registrar.rb +215 -0
  92. data/hanami-3.0.1/lib/hanami/universal_logger.rb +250 -0
  93. data/hanami-3.0.1/lib/hanami/version.rb +45 -0
  94. data/hanami-3.0.1/lib/hanami/web/rack_logger.rb +126 -0
  95. data/hanami-3.0.1/lib/hanami/web/welcome.html.erb +584 -0
  96. data/hanami-3.0.1/lib/hanami/web/welcome.rb +46 -0
  97. data/hanami-3.0.1/lib/hanami.rb +276 -0
  98. data/piko-lite-box.gemspec +11 -0
  99. metadata +137 -0
@@ -0,0 +1,20 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2015-2026 Hanakai team
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
6
+ this software and associated documentation files (the "Software"), to deal in
7
+ the Software without restriction, including without limitation the rights to
8
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9
+ the Software, and to permit persons to whom the Software is furnished to do so,
10
+ subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17
+ FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18
+ COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19
+ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,89 @@
1
+ <!--- This file is synced from hanakai-rb/repo-sync -->
2
+
3
+ [actions]: https://github.com/hanami/hanami/actions
4
+ [chat]: https://discord.gg/naQApPAsZB
5
+ [forum]: https://discourse.hanamirb.org
6
+ [rubygem]: https://rubygems.org/gems/hanami
7
+
8
+ # Hanami [![Gem Version](https://badge.fury.io/rb/hanami.svg)][rubygem] [![CI Status](https://github.com/hanami/hanami/workflows/CI/badge.svg)][actions]
9
+
10
+ [![Forum](https://img.shields.io/badge/Forum-dc360f?logo=discourse&logoColor=white)][forum]
11
+ [![Chat](https://img.shields.io/badge/Chat-717cf8?logo=discord&logoColor=white)][chat]
12
+
13
+ **A flexible framework for maintainable Ruby apps.**
14
+
15
+ Hanami is a **full-stack** Ruby web framework. It's made up of smaller, single-purpose libraries.
16
+
17
+ This repository is for the full-stack framework, which provides the glue that ties all the parts together:
18
+
19
+ * [**Hanami::Router**](https://github.com/hanami/router) - Rack compatible HTTP router for Ruby
20
+ * [**Hanami::Action**](https://github.com/hanami/hanami-action) - Full featured, fast and testable actions for Rack
21
+ * [**Hanami::View**](https://github.com/hanami/view) - Presentation with a separation between views and templates
22
+ * [**Hanami::DB**](https://github.com/hanami/db) - Database integration, complete with migrations, repositories, relations, and structs
23
+ * [**Hanami::Assets**](https://github.com/hanami/assets) - Assets management for Ruby
24
+
25
+ These components are designed to be used independently or together in a Hanami application.
26
+
27
+ ## Installation
28
+
29
+ ```shell
30
+ gem install hanami
31
+ ```
32
+
33
+ ## Usage
34
+
35
+ ```shell
36
+ hanami new bookshelf
37
+ cd bookshelf && bundle
38
+ bundle exec hanami dev
39
+ # Now visit http://localhost:2300
40
+ ```
41
+
42
+ Please follow along with the [Getting Started guide](https://guides.hanamirb.org/getting-started/).
43
+
44
+ ## Contributing
45
+
46
+ 1. Fork it (https://github.com/hanami/hanami/fork)
47
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
48
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
49
+ 4. Push to the branch (`git push origin my-new-feature`)
50
+ 5. Create a new Pull Request
51
+
52
+ In addition to contributing code, you can help to triage issues. This can include reproducing bug reports, or asking for vital information such as version numbers or reproduction instructions. If you would like to start triaging issues, one easy way to get started is to [subscribe to hanami on CodeTriage](https://www.codetriage.com/hanami/hanami).
53
+
54
+ ### Tests
55
+
56
+ To run all test suite:
57
+
58
+ ```shell
59
+ $ bundle exec rake
60
+ ```
61
+
62
+ To run all the unit tests:
63
+
64
+ ```shell
65
+ $ bundle exec rspec spec/unit
66
+ ```
67
+
68
+ To run all the integration tests:
69
+
70
+ ```shell
71
+ $ bundle exec rspec spec/integration
72
+ ```
73
+
74
+ To run a single test:
75
+
76
+ ```shell
77
+ $ bundle exec rspec path/to/spec.rb
78
+ ```
79
+
80
+ ## Links
81
+
82
+ - [User documentation](https://hanamirb.org)
83
+ - [API documentation](http://rubydoc.info/gems/hanami)
84
+
85
+
86
+ ## License
87
+
88
+ See `LICENSE` file.
89
+
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ # This file is synced from hanakai-rb/repo-sync. To update it, edit repo-sync.yml.
4
+
5
+ lib = File.expand_path("lib", __dir__)
6
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
7
+ require "hanami/version"
8
+
9
+ Gem::Specification.new do |spec|
10
+ spec.name = "hanami"
11
+ spec.authors = ["Hanakai team"]
12
+ spec.email = ["info@hanakai.org"]
13
+ spec.license = "MIT"
14
+ spec.version = Hanami::VERSION.dup
15
+
16
+ spec.summary = "A flexible framework for maintainable Ruby apps"
17
+ spec.description = spec.summary
18
+ spec.homepage = "https://hanamirb.org"
19
+ spec.files = Dir["CHANGELOG.md", "LICENSE", "README.md", "hanami.gemspec", "lib/**/*"]
20
+ spec.bindir = "exe"
21
+ spec.executables = Dir["exe/*"].map { |f| File.basename(f) }
22
+ spec.require_paths = ["lib"]
23
+
24
+ spec.extra_rdoc_files = ["README.md", "CHANGELOG.md", "LICENSE"]
25
+
26
+ spec.metadata["changelog_uri"] = "https://github.com/hanami/hanami/blob/main/CHANGELOG.md"
27
+ spec.metadata["source_code_uri"] = "https://github.com/hanami/hanami"
28
+ spec.metadata["bug_tracker_uri"] = "https://github.com/hanami/hanami/issues"
29
+ spec.metadata["funding_uri"] = "https://github.com/sponsors/hanami"
30
+
31
+ spec.required_ruby_version = ">= 3.3"
32
+
33
+ spec.add_runtime_dependency "bundler", ">= 2.0"
34
+ spec.add_runtime_dependency "dry-configurable", "~> 1.0", ">= 1.2.0", "< 2"
35
+ spec.add_runtime_dependency "dry-core", "~> 1.0", "< 2"
36
+ spec.add_runtime_dependency "dry-inflector", "~> 1.0", ">= 1.1.0", "< 2"
37
+ spec.add_runtime_dependency "dry-monitor", "~> 1.0", ">= 1.0.1", "< 2"
38
+ spec.add_runtime_dependency "dry-system", "~> 1.1"
39
+ spec.add_runtime_dependency "dry-logger", "~> 1.2", "< 2"
40
+ spec.add_runtime_dependency "hanami-cli", ">= 2.3.1"
41
+ spec.add_runtime_dependency "hanami-utils", "~> 3.0.0"
42
+ spec.add_runtime_dependency "json", ">= 2.7.2"
43
+ spec.add_runtime_dependency "zeitwerk", "~> 2.6"
44
+ spec.add_runtime_dependency "rack-session"
45
+ spec.add_development_dependency "rspec", "~> 3.8"
46
+ spec.add_development_dependency "rack-test", "~> 2.0"
47
+ spec.add_development_dependency "rake", "~> 13.0"
48
+ end
49
+
@@ -0,0 +1,197 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "constants"
4
+ require_relative "env"
5
+
6
+ module Hanami
7
+ # The Hanami app is a singular slice tasked with managing the core components of the app and
8
+ # coordinating overall app boot.
9
+ #
10
+ # For smaller apps, the app may be the only slice present, whereas larger apps may consist of many
11
+ # slices, with the app reserved for holding a small number of shared components only.
12
+ #
13
+ # @see Slice
14
+ #
15
+ # @api public
16
+ # @since 2.0.0
17
+ class App < Slice
18
+ @_mutex = Mutex.new
19
+
20
+ # @api private
21
+ # @since 2.0.0
22
+ def self.inherited(subclass)
23
+ super
24
+
25
+ Hanami.app = subclass
26
+
27
+ subclass.extend(ClassMethods)
28
+
29
+ @_mutex.synchronize do
30
+ subclass.class_eval do
31
+ @config = Hanami::Config.new(app_name: slice_name, env: Hanami.env)
32
+ Hanami::Env.load
33
+ end
34
+ end
35
+ end
36
+
37
+ # App class interface
38
+ module ClassMethods
39
+ # Returns the app's config.
40
+ #
41
+ # @return [Hanami::Config]
42
+ #
43
+ # @api public
44
+ # @since 2.0.0
45
+ attr_reader :config
46
+
47
+ # Returns the app's {SliceName}.
48
+ #
49
+ # @return [Hanami::SliceName]
50
+ #
51
+ # @see Slice::ClassMethods#slice_name
52
+ #
53
+ # @api public
54
+ # @since 2.0.0
55
+ def app_name
56
+ slice_name
57
+ end
58
+
59
+ # Prepares the $LOAD_PATH based on the app's configured root, prepending the `lib/` directory
60
+ # if it exists. If the lib directory is already added, this will do nothing.
61
+ #
62
+ # In ordinary circumstances, you should never have to call this method: this method is called
63
+ # immediately upon subclassing {Hanami::App}, as a convenicence to put lib/ (under the default
64
+ # root of `Dir.pwd`) on the load path automatically. This is helpful if you need to require
65
+ # files inside the subclass body for performing certain app configuration steps.
66
+ #
67
+ # If you change your app's `config.root` and you need to require files from its `lib/`
68
+ # directory within your {App} subclass body, you should call {.prepare_load_path} explicitly
69
+ # after setting the new root.
70
+ #
71
+ # Otherwise, this method is called again as part of the app {.prepare} step, so if you've
72
+ # changed your app's root and do _not_ need to require files within your {App} subclass body,
73
+ # then you don't need to call this method.
74
+ #
75
+ # @example
76
+ # module MyApp
77
+ # class App < Hanami::App
78
+ # config.root = Pathname(__dir__).join("../src")
79
+ # prepare_load_path
80
+ #
81
+ # # You can make requires for your files here
82
+ # end
83
+ # end
84
+ #
85
+ # @return [self]
86
+ #
87
+ # @api public
88
+ # @since 2.0.0
89
+ def prepare_load_path
90
+ if (lib_path = root.join(LIB_DIR)).directory?
91
+ path = lib_path.realpath.to_s
92
+ $LOAD_PATH.prepend(path) unless $LOAD_PATH.include?(path)
93
+ end
94
+
95
+ self
96
+ end
97
+
98
+ private
99
+
100
+ def prepare_all
101
+ prepare_load_path
102
+
103
+ # Make app-wide notifications available as early as possible
104
+ container.use(:notifications)
105
+
106
+ # Ensure all basic slice preparation is complete before we make adjustments below (which
107
+ # rely on the basic prepare steps having already run)
108
+ super
109
+
110
+ # Run specific prepare steps for the app slice. Note also that some standard steps have been
111
+ # skipped via the empty method overrides below.
112
+ prepare_app_component_dirs
113
+ prepare_app_providers
114
+ end
115
+
116
+ # Skip standard slice prepare steps that do not apply to the app
117
+ def prepare_container_component_dirs; end
118
+ def prepare_container_imports; end
119
+
120
+ # rubocop:disable Metrics/AbcSize
121
+
122
+ def prepare_app_component_dirs
123
+ # Component files in both `app/` and `app/lib/` define classes in the
124
+ # app's namespace
125
+
126
+ if root.join(APP_DIR, LIB_DIR).directory?
127
+ container.config.component_dirs.add(File.join(APP_DIR, LIB_DIR)) do |dir|
128
+ dir.namespaces.add_root(key: nil, const: app_name.name)
129
+ end
130
+ end
131
+
132
+ # When auto-registering components in `app/`, ignore files in `app/lib/` (these will be
133
+ # auto-registered as above), as well as the configured no_auto_register_paths
134
+ no_auto_register_paths = ([LIB_DIR] + config.no_auto_register_paths)
135
+ .map { |path|
136
+ path.end_with?(File::SEPARATOR) ? path : "#{path}#{File::SEPARATOR}"
137
+ }
138
+
139
+ if root.join(APP_DIR).directory?
140
+ container.config.component_dirs.add(APP_DIR) do |dir|
141
+ dir.namespaces.add_root(key: nil, const: app_name.name)
142
+ dir.auto_register = -> component {
143
+ relative_path = component.file_path.relative_path_from(root.join(APP_DIR)).to_s
144
+ !relative_path.start_with?(*no_auto_register_paths)
145
+ }
146
+ end
147
+ end
148
+ end
149
+
150
+ def prepare_app_providers
151
+ require_relative "providers/inflector"
152
+ register_provider(:inflector, source: Hanami::Providers::Inflector)
153
+
154
+ # Allow the logger to be replaced by users with a manual provider, for advanced cases.
155
+ #
156
+ # Require the logger provider source up front, to make `configure_provider(:logger)`
157
+ # possible.
158
+ require_relative "providers/logger"
159
+ unless container.providers[:logger]
160
+ register_provider(:logger, source: Hanami::Providers::Logger)
161
+ end
162
+
163
+ # Ensure the logger is wrapped by `Hanami::UniversalLogger`, even if manually registered in a
164
+ # user-defined provider, guaranteeing Hanami's structured and tagged logging interface across
165
+ # the framework.
166
+ container.providers[:logger].source.after(:start) do
167
+ container.decorate(:logger) { |logger| Hanami::UniversalLogger[logger] }
168
+ end
169
+
170
+ if Hanami.bundled?("rack")
171
+ require_relative "providers/rack"
172
+ register_provider(:rack, source: Hanami::Providers::Rack, namespace: true)
173
+ end
174
+
175
+ if Hanami.bundled?("hanami-db")
176
+ register_provider(:db_logging, source: Hanami::Providers::DBLogging)
177
+ end
178
+ end
179
+
180
+ def prepare_autoloader
181
+ autoloader.tag = "hanami.app.#{slice_name.name}"
182
+
183
+ # Component dirs are automatically pushed to the autoloader by dry-system's zeitwerk plugin.
184
+ # This method adds other dirs that are not otherwise configured as component dirs.
185
+
186
+ # Autoload classes from `lib/[app_namespace]/`
187
+ if root.join(LIB_DIR, app_name.name).directory?
188
+ autoloader.push_dir(root.join(LIB_DIR, app_name.name), namespace: namespace)
189
+ end
190
+
191
+ autoloader.setup
192
+ end
193
+
194
+ # rubocop:enable Metrics/AbcSize
195
+ end
196
+ end
197
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "setup"
4
+
5
+ Hanami.boot
@@ -0,0 +1,140 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Hanami
4
+ class Config
5
+ class Actions
6
+ # Config for Content Security Policy in Hanami apps
7
+ #
8
+ # @since 2.0.0
9
+ class ContentSecurityPolicy
10
+ # @since 2.0.0
11
+ # @api private
12
+ def initialize(&blk)
13
+ @policy = {
14
+ base_uri: "'self'",
15
+ child_src: "'self'",
16
+ connect_src: "'self'",
17
+ default_src: "'none'",
18
+ font_src: "'self'",
19
+ form_action: "'self'",
20
+ frame_ancestors: "'self'",
21
+ frame_src: "'self'",
22
+ img_src: "'self' https: data:",
23
+ media_src: "'self'",
24
+ object_src: "'none'",
25
+ script_src: "'self'",
26
+ style_src: "'self' 'unsafe-inline' https:"
27
+ }
28
+
29
+ blk&.(self)
30
+ end
31
+
32
+ # @since 2.0.0
33
+ # @api private
34
+ def initialize_copy(original_object)
35
+ @policy = original_object.instance_variable_get(:@policy).dup
36
+ super
37
+ end
38
+
39
+ # Get a CSP setting
40
+ #
41
+ # @param key [Symbol] the underscored name of the CPS setting
42
+ # @return [String,NilClass] the CSP setting, if any
43
+ #
44
+ # @since 2.0.0
45
+ # @api public
46
+ #
47
+ # @example
48
+ # module MyApp
49
+ # class App < Hanami::App
50
+ # config.actions.content_security_policy[:base_uri] # => "'self'"
51
+ # end
52
+ # end
53
+ def [](key)
54
+ @policy[key]
55
+ end
56
+
57
+ # Set a CSP setting
58
+ #
59
+ # @param key [Symbol] the underscored name of the CPS setting
60
+ # @param value [String] the CSP setting value
61
+ #
62
+ # @since 2.0.0
63
+ # @api public
64
+ #
65
+ # @example Replace a default value
66
+ # module MyApp
67
+ # class App < Hanami::App
68
+ # config.actions.content_security_policy[:plugin_types] = nil
69
+ # end
70
+ # end
71
+ #
72
+ # @example Append to a default value
73
+ # module MyApp
74
+ # class App < Hanami::App
75
+ # config.actions.content_security_policy[:script_src] += " https://my.cdn.test"
76
+ # end
77
+ # end
78
+ def []=(key, value)
79
+ @policy[key] = value
80
+ end
81
+
82
+ # Deletes a CSP key
83
+ #
84
+ # @param key [Symbol] the underscored name of the CPS setting
85
+ #
86
+ # @since 2.0.0
87
+ # @api public
88
+ #
89
+ # @example
90
+ # module MyApp
91
+ # class App < Hanami::App
92
+ # config.actions.content_security_policy.delete(:object_src)
93
+ # end
94
+ # end
95
+ def delete(key)
96
+ @policy.delete(key)
97
+ end
98
+
99
+ # Returns true if 'nonce' is used in any of the policies.
100
+ #
101
+ # @return [Boolean]
102
+ #
103
+ # @api public
104
+ # @since 2.3.0
105
+ def nonce?
106
+ @policy.any? { _2.match?(/'nonce'/) }
107
+ end
108
+
109
+ # Returns an array of middleware name to support 'nonce' in
110
+ # policies, or an empty array if 'nonce' is not used.
111
+ #
112
+ # @return [Array<(Symbol, Array)>]
113
+ #
114
+ # @api public
115
+ # @since 2.3.0
116
+ def middleware
117
+ return [] unless nonce?
118
+
119
+ [Hanami::Middleware::ContentSecurityPolicyNonce]
120
+ end
121
+
122
+ # @since 2.0.0
123
+ # @api private
124
+ def to_s
125
+ @policy.map do |key, value|
126
+ "#{dasherize(key)} #{value}"
127
+ end.join(";")
128
+ end
129
+
130
+ private
131
+
132
+ # @since 2.0.0
133
+ # @api private
134
+ def dasherize(key)
135
+ key.to_s.gsub("_", "-")
136
+ end
137
+ end
138
+ end
139
+ end
140
+ end
@@ -0,0 +1,57 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Hanami
4
+ class Config
5
+ class Actions
6
+ # Wrapper for app-level config of HTTP cookies for Hanami actions.
7
+ #
8
+ # This decorates the hash of cookie options that is otherwise directly configurable on
9
+ # actions, and adds the `enabled?` method to allow app base action to determine whether to
10
+ # include the `Action::Cookies` module.
11
+ #
12
+ # @api public
13
+ # @since 2.0.0
14
+ class Cookies
15
+ # Returns the cookie options.
16
+ #
17
+ # @return [Hash]
18
+ #
19
+ # @api public
20
+ # @since 2.0.0
21
+ attr_reader :options
22
+
23
+ # Returns a new `Cookies`.
24
+ #
25
+ # You should not need to initialize this class directly. Instead use
26
+ # {Hanami::Config::Actions#cookies}.
27
+ #
28
+ # @api private
29
+ # @since 2.0.0
30
+ def initialize(options)
31
+ @options = options
32
+ end
33
+
34
+ # Returns true if any cookie options have been provided.
35
+ #
36
+ # @return [Boolean]
37
+ #
38
+ # @api public
39
+ # @since 2.0.0
40
+ def enabled?
41
+ !options.nil?
42
+ end
43
+
44
+ # Returns the cookie options.
45
+ #
46
+ # If no options have been provided, returns an empty hash.
47
+ #
48
+ # @return [Hash]
49
+ #
50
+ # @api public
51
+ def to_h
52
+ options.to_h
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,83 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "hanami/utils/string"
4
+ require "hanami/utils/class"
5
+
6
+ module Hanami
7
+ class Config
8
+ class Actions
9
+ # Config for HTTP session middleware in Hanami actions.
10
+ #
11
+ # @api public
12
+ # @since 2.0.0
13
+ class Sessions
14
+ # Returns the configured session storage
15
+ #
16
+ # @return [Symbol]
17
+ #
18
+ # @api public
19
+ # @since 2.0.0
20
+ attr_reader :storage
21
+
22
+ # Returns the configured session storage options
23
+ #
24
+ # @return [Array]
25
+ #
26
+ # @api public
27
+ # @since 2.0.0
28
+ attr_reader :options
29
+
30
+ # Returns a new `Sessions`.
31
+ #
32
+ # You should not need to initialize this class directly. Instead use
33
+ # {Hanami::Config::Actions#sessions=}.
34
+ #
35
+ # @example
36
+ # config.actions.sessions = :cookie, {secret: "xyz"}
37
+ #
38
+ # @api private
39
+ # @since 2.0.0
40
+ def initialize(storage = nil, *options)
41
+ @storage = storage
42
+ @options = options
43
+ end
44
+
45
+ # Returns true if sessions have been enabled.
46
+ #
47
+ # @return [Boolean]
48
+ #
49
+ # @api public
50
+ # @since 2.0.0
51
+ def enabled?
52
+ !storage.nil?
53
+ end
54
+
55
+ # Returns an array of the session storage middleware name and its options, or an empty array
56
+ # if sessions have not been enabled.
57
+ #
58
+ # @return [Array<(Symbol, Array)>]
59
+ #
60
+ # @api public
61
+ # @since 2.0.0
62
+ def middleware
63
+ return [] unless enabled?
64
+
65
+ [storage_middleware, options].flatten(1)
66
+ end
67
+
68
+ private
69
+
70
+ def storage_middleware
71
+ require_storage
72
+
73
+ name = Utils::String.classify(storage)
74
+ Utils::Class.load!(name, ::Rack::Session)
75
+ end
76
+
77
+ def require_storage
78
+ require "rack/session/#{storage}"
79
+ end
80
+ end
81
+ end
82
+ end
83
+ end