securial 1.0.1 → 1.0.3

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 (55) hide show
  1. checksums.yaml +4 -4
  2. data/.yardopts +4 -0
  3. data/README.md +19 -12
  4. data/app/controllers/concerns/securial/identity.rb +91 -2
  5. data/app/controllers/securial/accounts_controller.rb +68 -5
  6. data/app/controllers/securial/application_controller.rb +34 -2
  7. data/app/controllers/securial/passwords_controller.rb +44 -4
  8. data/app/controllers/securial/role_assignments_controller.rb +55 -4
  9. data/app/controllers/securial/roles_controller.rb +54 -0
  10. data/app/controllers/securial/sessions_controller.rb +77 -3
  11. data/app/controllers/securial/status_controller.rb +24 -0
  12. data/app/controllers/securial/users_controller.rb +54 -0
  13. data/app/jobs/securial/application_job.rb +9 -0
  14. data/app/mailers/securial/application_mailer.rb +12 -0
  15. data/app/mailers/securial/securial_mailer.rb +30 -0
  16. data/app/models/concerns/securial/password_resettable.rb +70 -0
  17. data/app/models/securial/application_record.rb +19 -0
  18. data/app/models/securial/current.rb +13 -0
  19. data/app/models/securial/role.rb +17 -0
  20. data/app/models/securial/role_assignment.rb +16 -0
  21. data/app/models/securial/session.rb +79 -1
  22. data/app/models/securial/user.rb +34 -0
  23. data/lib/generators/factory_bot/model/model_generator.rb +1 -0
  24. data/lib/securial/auth/auth_encoder.rb +78 -0
  25. data/lib/securial/auth/session_creator.rb +49 -0
  26. data/lib/securial/auth/token_generator.rb +74 -0
  27. data/lib/securial/auth.rb +44 -6
  28. data/lib/securial/cli.rb +124 -0
  29. data/lib/securial/config/signature.rb +116 -5
  30. data/lib/securial/config/validation.rb +91 -0
  31. data/lib/securial/config.rb +49 -2
  32. data/lib/securial/engine.rb +41 -0
  33. data/lib/securial/error/auth.rb +52 -0
  34. data/lib/securial/error/base_securial_error.rb +51 -0
  35. data/lib/securial/error/config.rb +33 -0
  36. data/lib/securial/error.rb +33 -3
  37. data/lib/securial/helpers/key_transformer.rb +106 -0
  38. data/lib/securial/helpers/normalizing_helper.rb +69 -0
  39. data/lib/securial/helpers/regex_helper.rb +122 -0
  40. data/lib/securial/helpers/roles_helper.rb +71 -2
  41. data/lib/securial/helpers.rb +48 -4
  42. data/lib/securial/logger/broadcaster.rb +89 -1
  43. data/lib/securial/logger/builder.rb +54 -1
  44. data/lib/securial/logger/formatter.rb +73 -0
  45. data/lib/securial/logger.rb +42 -1
  46. data/lib/securial/middleware/request_tag_logger.rb +80 -0
  47. data/lib/securial/middleware/response_headers.rb +51 -3
  48. data/lib/securial/middleware/transform_request_keys.rb +143 -20
  49. data/lib/securial/middleware/transform_response_keys.rb +84 -4
  50. data/lib/securial/middleware.rb +40 -9
  51. data/lib/securial/security/request_rate_limiter.rb +47 -1
  52. data/lib/securial/security.rb +37 -6
  53. data/lib/securial/version.rb +8 -1
  54. data/lib/securial.rb +36 -0
  55. metadata +21 -15
@@ -1,15 +1,76 @@
1
+ # @title Securial Transform Response Keys Middleware
2
+ #
3
+ # Rack middleware for transforming JSON response keys to client-preferred formats.
4
+ #
5
+ # This middleware automatically converts outgoing JSON response keys from Ruby's
6
+ # snake_case convention to the configured format (camelCase, PascalCase, etc.) to
7
+ # match client application expectations. It only processes JSON responses and
8
+ # preserves the original response structure and content.
9
+ #
10
+ # @example Adding middleware to Rails application
11
+ # # config/application.rb
12
+ # config.middleware.use Securial::Middleware::TransformResponseKeys
13
+ #
14
+ # @example Response transformation with lowerCamelCase
15
+ # # Original Rails response:
16
+ # { "user_name": "john", "email_address": "john@example.com" }
17
+ #
18
+ # # Transformed for client:
19
+ # { "userName": "john", "emailAddress": "john@example.com" }
20
+ #
21
+ # @example Response transformation with UpperCamelCase
22
+ # # Configuration: config.response_keys_format = :UpperCamelCase
23
+ # # Original: { "user_profile": { "first_name": "John" } }
24
+ # # Transformed: { "UserProfile": { "FirstName": "John" } }
25
+ #
26
+ require "json"
27
+
1
28
  module Securial
2
29
  module Middleware
3
- # This middleware transforms response keys to a specified format.
4
- # It uses the KeyTransformer helper to apply the transformation.
30
+ # Rack middleware that transforms JSON response keys to configured format.
31
+ #
32
+ # This middleware enables Rails applications to output responses in
33
+ # the naming convention expected by client applications (JavaScript,
34
+ # mobile apps, etc.) while maintaining Ruby's snake_case internally.
5
35
  #
6
- # It reads the response body if the content type is JSON and transforms
7
- # the keys to the specified format (default is lowerCamelCase).
8
36
  class TransformResponseKeys
37
+ # Initializes the middleware with the Rack application and optional format.
38
+ #
39
+ # The format parameter is deprecated in favor of the global configuration
40
+ # setting `Securial.configuration.response_keys_format`.
41
+ #
42
+ # @param [#call] app The Rack application to wrap
43
+ # @param [Symbol] format Deprecated: The key format to use (defaults to :lowerCamelCase)
44
+ #
45
+ # @example
46
+ # middleware = TransformResponseKeys.new(app)
47
+ #
48
+ # @deprecated Use `Securial.configuration.response_keys_format` instead of format parameter
49
+ #
9
50
  def initialize(app, format: :lowerCamelCase)
10
51
  @app = app
11
52
  end
12
53
 
54
+ # Processes the response and transforms JSON keys if applicable.
55
+ #
56
+ # Intercepts JSON responses, parses the body, transforms all keys to
57
+ # the configured format using the KeyTransformer helper, and replaces
58
+ # the response body with the transformed JSON. Non-JSON responses
59
+ # pass through unchanged.
60
+ #
61
+ # @param [Hash] env The Rack environment hash
62
+ # @return [Array] The Rack response array [status, headers, body] with transformed keys
63
+ #
64
+ # @example JSON transformation
65
+ # # Original response: { "first_name": "John", "last_name": "Doe" }
66
+ # # Transformed response: { "firstName": "John", "lastName": "Doe" }
67
+ #
68
+ # @example Non-JSON responses
69
+ # # HTML, XML, and other content types pass through unchanged
70
+ #
71
+ # @example Empty or malformed JSON handling
72
+ # # Empty responses and invalid JSON are left unchanged
73
+ #
13
74
  def call(env)
14
75
  status, headers, response = @app.call(env)
15
76
 
@@ -33,10 +94,29 @@ module Securial
33
94
 
34
95
  private
35
96
 
97
+ # Checks if the response contains JSON content.
98
+ #
99
+ # @param [Hash] headers The response headers hash
100
+ # @return [Boolean] true if the response has JSON content type
101
+ # @api private
102
+ #
36
103
  def json_response?(headers)
37
104
  headers["Content-Type"]&.include?("application/json")
38
105
  end
39
106
 
107
+ # Extracts the complete response body from the response object.
108
+ #
109
+ # Iterates through the response body parts and concatenates them
110
+ # into a single string for JSON parsing and transformation.
111
+ #
112
+ # @param [#each] response The response body object (responds to #each)
113
+ # @return [String] The complete response body as a string
114
+ # @api private
115
+ #
116
+ # @example
117
+ # body = extract_body(response)
118
+ # # => '{"user_name":"john","email":"john@example.com"}'
119
+ #
40
120
  def extract_body(response)
41
121
  response_body = ""
42
122
  response.each { |part| response_body << part }
@@ -1,16 +1,47 @@
1
+ # @title Securial Middleware Components
2
+ #
3
+ # Rack middleware components for the Securial framework.
4
+ #
5
+ # This file serves as the entry point for middleware-related functionality in Securial,
6
+ # loading specialized middleware classes that provide features like request/response
7
+ # processing, logging enhancements, and security header management.
8
+ #
1
9
  require "securial/middleware/request_tag_logger"
2
10
  require "securial/middleware/transform_request_keys"
3
11
  require "securial/middleware/transform_response_keys"
4
12
  require "securial/middleware/response_headers"
5
13
 
6
14
  module Securial
7
- module Middleware
8
- # This module serves as a namespace for all middleware components in the Securial gem.
9
- # It currently includes the RequestTagLogger middleware, which tags logs with request IDs.
10
- #
11
- # Additional middleware can be added here as the gem evolves.
12
- #
13
- # Example usage:
14
- # use Securial::Middleware::RequestTagLogger
15
- end
15
+ # Namespace for Rack middleware components in the Securial framework.
16
+ #
17
+ # This module contains several middleware components that enhance Rails applications:
18
+ #
19
+ # - {RequestTagLogger} - Tags logs with request IDs for better traceability
20
+ # - {TransformRequestKeys} - Transforms incoming request parameter keys to a consistent format
21
+ # - {TransformResponseKeys} - Transforms outgoing response JSON keys to match client conventions
22
+ # - {ResponseHeaders} - Adds security headers to responses based on configuration
23
+ #
24
+ # @example Using middleware in a Rails application (config/application.rb)
25
+ # module YourApp
26
+ # class Application < Rails::Application
27
+ # # Add request logging with unique IDs
28
+ # config.middleware.use Securial::Middleware::RequestTagLogger
29
+ #
30
+ # # Transform request keys from camelCase to snake_case
31
+ # config.middleware.use Securial::Middleware::TransformRequestKeys
32
+ #
33
+ # # Transform response keys from snake_case to camelCase
34
+ # config.middleware.use Securial::Middleware::TransformResponseKeys
35
+ #
36
+ # # Add security headers to all responses
37
+ # config.middleware.use Securial::Middleware::ResponseHeaders
38
+ # end
39
+ # end
40
+ #
41
+ # @see Securial::Middleware::RequestTagLogger
42
+ # @see Securial::Middleware::TransformRequestKeys
43
+ # @see Securial::Middleware::TransformResponseKeys
44
+ # @see Securial::Middleware::ResponseHeaders
45
+ #
46
+ module Middleware; end
16
47
  end
@@ -1,11 +1,57 @@
1
+ # @title Securial Request Rate Limiter
2
+ #
3
+ # Rate limiting middleware for protecting authentication endpoints in the Securial framework.
4
+ #
5
+ # This file implements rate limiting for sensitive endpoints like login and password reset,
6
+ # protecting them from brute force attacks, credential stuffing, and denial of service attempts.
7
+ # It uses the Rack::Attack middleware to track and limit request rates based on IP address
8
+ # and provided credentials.
9
+ #
10
+ # @example Basic configuration in a Rails initializer
11
+ # # In config/initializers/securial.rb
12
+ # Securial.configure do |config|
13
+ # config.rate_limit_requests_per_minute = 5
14
+ # config.rate_limit_response_status = 429
15
+ # config.rate_limit_response_message = "Too many requests. Please try again later."
16
+ # end
17
+ #
18
+ # # Apply rate limiting
19
+ # Securial::Security::RequestRateLimiter.apply!
20
+ #
1
21
  require "rack/attack"
2
22
  require "securial/config"
3
23
 
4
24
  module Securial
5
25
  module Security
26
+ # Protects authentication endpoints with configurable rate limiting.
27
+ #
28
+ # This module provides Rack::Attack-based rate limiting for sensitive Securial
29
+ # endpoints, preventing brute force attacks and abuse. It limits requests based
30
+ # on both IP address and credential values (like email address), providing
31
+ # multi-dimensional protection against different attack vectors.
32
+ #
33
+ # Protected endpoints include:
34
+ # - Login attempts (/sessions/login)
35
+ # - Password reset requests (/password/forgot)
36
+ #
6
37
  module RequestRateLimiter
7
38
  extend self
8
39
 
40
+ # Applies rate limiting rules to the Rack::Attack middleware.
41
+ #
42
+ # This method configures Rack::Attack with throttling rules for sensitive endpoints
43
+ # and sets up a custom JSON response format for throttled requests. It should be
44
+ # called during application initialization, typically in a Rails initializer.
45
+ #
46
+ # Rate limits are defined using settings from the Securial configuration:
47
+ # - rate_limit_requests_per_minute: Maximum requests allowed per minute
48
+ # - rate_limit_response_status: HTTP status code to return (typically 429)
49
+ # - rate_limit_response_message: Message to include in throttled responses
50
+ #
51
+ # @return [void]
52
+ # @see Securial::Config::Configuration
53
+ # @see Rack::Attack
54
+ #
9
55
  def apply! # rubocop:disable Metrics/MethodLength
10
56
  resp_status = Securial.configuration.rate_limit_response_status
11
57
  resp_message = Securial.configuration.rate_limit_response_message
@@ -36,7 +82,7 @@ module Securial
36
82
  "Content-Type" => "application/json",
37
83
  "Retry-After" => retry_after.to_s,
38
84
  },
39
- [{ error: resp_message }.to_json],
85
+ [{ errors: [resp_message] }.to_json],
40
86
  ]
41
87
  end
42
88
  end
@@ -1,8 +1,39 @@
1
+ # @title Securial Security Components
2
+ #
3
+ # Security components and protections for the Securial framework.
4
+ #
5
+ # This file serves as the entry point for security-related functionality in Securial,
6
+ # loading specialized security modules that provide protection mechanisms including
7
+ # rate limiting, CSRF protection, and other security measures to safeguard
8
+ # Securial-powered applications.
9
+ #
10
+ # @example Using the rate limiter
11
+ # # Set up a rate limiter for login attempts
12
+ # limiter = Securial::Security::RequestRateLimiter.new(
13
+ # max_requests: 5,
14
+ # period: 1.minute,
15
+ # block_duration: 15.minutes
16
+ # )
17
+ #
18
+ # # Check if a request is allowed
19
+ # if limiter.allowed?(request.ip)
20
+ # # Process login attempt
21
+ # else
22
+ # # Return rate limit exceeded response
23
+ # end
24
+ #
1
25
  require "securial/security/request_rate_limiter"
2
26
 
3
- module Securial
4
- module Security
5
- # This module serves as a namespace for security-related functionality.
6
- # It can be extended with additional security features in the future.
7
- end
8
- end
27
+ module Securial
28
+ # Namespace for security-related functionality in the Securial framework.
29
+ #
30
+ # The Security module contains components that implement various security
31
+ # measures to protect applications from common attacks and threats:
32
+ #
33
+ # - {RequestRateLimiter} - Protection against brute force and DoS attacks
34
+ # - Additional security components may be added in future versions
35
+ #
36
+ # @see Securial::Security::RequestRateLimiter
37
+ #
38
+ module Security; end
39
+ end
@@ -1,3 +1,10 @@
1
1
  module Securial
2
- VERSION = "1.0.1".freeze
2
+ # Current version of the Securial gem.
3
+ #
4
+ # This constant is used by the gem specification to determine the version of the gem
5
+ # when it is built and published to RubyGems. It follows Semantic Versioning 2.0.0.
6
+ #
7
+ # @see https://semver.org/ Semantic Versioning 2.0.0
8
+ # @return [String] the current version in the format "major.minor.patch"
9
+ VERSION = "1.0.3".freeze
3
10
  end
data/lib/securial.rb CHANGED
@@ -1,11 +1,47 @@
1
+ # Main entry point for the Securial gem.
2
+ #
3
+ # This file serves as the primary entry point for the Securial gem,
4
+ # requiring necessary dependencies, setting up the module structure,
5
+ # and establishing method delegation.
6
+ #
7
+ # The Securial gem is a mountable Rails engine that provides authentication
8
+ # and authorization capabilities for Rails applications, supporting JWT,
9
+ # API tokens, and session-based authentication.
10
+ #
11
+ # @example Basic usage in a Rails application
12
+ # # In Gemfile
13
+ # gem 'securial'
14
+ #
15
+ # # In routes.rb
16
+ # Rails.application.routes.draw do
17
+ # mount Securial::Engine => '/securial'
18
+ # end
19
+ #
20
+ # @see Securial::Engine
21
+ # @see Securial::VERSION
22
+ #
1
23
  require "securial/version"
2
24
  require "securial/engine"
3
25
 
4
26
  require "jbuilder"
5
27
 
28
+ # Main namespace for the Securial authentication and authorization framework.
29
+ #
30
+ # This module provides access to core functionality of the Securial gem
31
+ # by exposing key helper methods and serving as the root namespace for
32
+ # all Securial components.
33
+ #
6
34
  module Securial
7
35
  extend self
8
36
 
37
+ # @!method protected_namespace
38
+ # Returns the namespace used for protected resources in the application.
39
+ # @return [String] the protected namespace designation
40
+
41
+ # @!method titleized_admin_role
42
+ # Returns the admin role name with proper title-case formatting.
43
+ # @return [String] the admin role title
44
+
9
45
  delegate :protected_namespace, to: Securial::Helpers::RolesHelper
10
46
  delegate :titleized_admin_role, to: Securial::Helpers::RolesHelper
11
47
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: securial
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.1
4
+ version: 1.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Aly Badawy
8
8
  bindir: bin
9
9
  cert_chain: []
10
- date: 2025-06-24 00:00:00.000000000 Z
10
+ date: 2025-06-27 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: rails
@@ -96,6 +96,7 @@ executables:
96
96
  extensions: []
97
97
  extra_rdoc_files: []
98
98
  files:
99
+ - ".yardopts"
99
100
  - MIT-LICENSE
100
101
  - README.md
101
102
  - Rakefile
@@ -205,22 +206,27 @@ homepage: https://github.com/AlyBadawy/Securial/wiki
205
206
  licenses:
206
207
  - MIT
207
208
  metadata:
208
- release_date: '2025-06-24'
209
- allowed_push_host: https://rubygems.org
210
209
  homepage_uri: https://github.com/AlyBadawy/Securial/wiki
210
+ release_date: '2025-06-27'
211
+ allowed_push_host: https://rubygems.org
211
212
  source_code_uri: https://github.com/AlyBadawy/Securial
213
+ documentation_uri: https://alybadawy.github.io/Securial/_index.html
212
214
  changelog_uri: https://github.com/AlyBadawy/Securial/blob/main/CHANGELOG.md
213
- post_install_message: "\n ---\n [SECURIAL] Thank you for installing Securial!\n\n
214
- \ Securial is a mountable Rails engine that provides robust, extensible\n authentication
215
- and access control for Rails applications. It supports JWT,\n API tokens, session-based
216
- auth, and is designed for easy integration with\n modern web and mobile apps.\n\n
217
- \ Usage:\n securial new APP_NAME [rails_options...] # Create a new Rails
218
- app with Securial pre-installed\n securial -v, --version #
219
- Show the Securial gem version\n securial -h, --help #
220
- Show this help message\n\n Example:\n securial new myapp --api --database=postgresql
221
- -T\n\n More Info:\n review the [changelog] and [WIKI] for more info on the
222
- latest\n changes and how to use this gem/engine:\n [Changelog]: https://github.com/AlyBadawy/Securial/blob/main/CHANGELOG.md\n
223
- \ [WIKI]: https://github.com/AlyBadawy/Securial/wiki\n ---\n "
215
+ wiki_uri: https://github.com/AlyBadawy/Securial/wiki
216
+ post_install_message: "\e[36m\n ▗▄▄▖▗▄▄▄▖ ▗▄▄▖▗▖ ▗▖▗▄▄▖ ▗▄▄▄▖ ▗▄▖ ▗▖\n▐▌ ▐▌ ▐▌
217
+ \ ▐▌ ▐▌▐▌ ▐▌ █ ▐▌ ▐▌▐▌\n ▝▀▚▖▐▛▀▀▘▐▌ ▐▌ ▐▌▐▛▀▚▖ █ ▐▛▀▜▌▐▌\n▗▄▄▞▘▐▙▄▄▖▝▚▄▄▖▝▚▄▞▘▐▌
218
+ ▐▌▗▄█▄▖▐▌ ▐▌▐▙▄▄▖\n\e[0m\n\n\e[32mThank you for installing Securial!\e[0m\n\n\e[37mSecurial
219
+ is a mountable Rails engine that provides robust, extensible\nauthentication and
220
+ access control for Rails applications. It supports JWT,\nAPI tokens, session-based
221
+ auth, and is designed for easy integration with\nmodern web and mobile apps.\e[0m\n\n\e[33mUsage:\e[0m\n
222
+ \ \e[36msecurial new APP_NAME [rails_options...]\e[0m # Create a new Rails app
223
+ with Securial pre-installed\n \e[36msecurial -v, --version\e[0m #
224
+ Show the Securial gem version\n \e[36msecurial -h, --help\e[0m #
225
+ Show this help message\n\n\e[33mExample:\e[0m\n \e[32msecurial new myapp --api
226
+ --database=postgresql -T\e[0m\n\n\e[33mMore Info:\e[0m\n \e[37mreview the [changelog]
227
+ and [WIKI] for more info on the latest\n changes and how to use this gem/engine:\e[0m\n
228
+ \ \e[34m[Changelog]: https://github.com/AlyBadawy/Securial/blob/main/CHANGELOG.md\e[0m\n
229
+ \ \e[34m[WIKI]: https://github.com/AlyBadawy/Securial/wiki\e[0m\n\e[90m---\e[0m\n"
224
230
  rdoc_options: []
225
231
  require_paths:
226
232
  - lib