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.
- checksums.yaml +4 -4
- data/.yardopts +4 -0
- data/README.md +19 -12
- data/app/controllers/concerns/securial/identity.rb +91 -2
- data/app/controllers/securial/accounts_controller.rb +68 -5
- data/app/controllers/securial/application_controller.rb +34 -2
- data/app/controllers/securial/passwords_controller.rb +44 -4
- data/app/controllers/securial/role_assignments_controller.rb +55 -4
- data/app/controllers/securial/roles_controller.rb +54 -0
- data/app/controllers/securial/sessions_controller.rb +77 -3
- data/app/controllers/securial/status_controller.rb +24 -0
- data/app/controllers/securial/users_controller.rb +54 -0
- data/app/jobs/securial/application_job.rb +9 -0
- data/app/mailers/securial/application_mailer.rb +12 -0
- data/app/mailers/securial/securial_mailer.rb +30 -0
- data/app/models/concerns/securial/password_resettable.rb +70 -0
- data/app/models/securial/application_record.rb +19 -0
- data/app/models/securial/current.rb +13 -0
- data/app/models/securial/role.rb +17 -0
- data/app/models/securial/role_assignment.rb +16 -0
- data/app/models/securial/session.rb +79 -1
- data/app/models/securial/user.rb +34 -0
- data/lib/generators/factory_bot/model/model_generator.rb +1 -0
- data/lib/securial/auth/auth_encoder.rb +78 -0
- data/lib/securial/auth/session_creator.rb +49 -0
- data/lib/securial/auth/token_generator.rb +74 -0
- data/lib/securial/auth.rb +44 -6
- data/lib/securial/cli.rb +124 -0
- data/lib/securial/config/signature.rb +116 -5
- data/lib/securial/config/validation.rb +91 -0
- data/lib/securial/config.rb +49 -2
- data/lib/securial/engine.rb +41 -0
- data/lib/securial/error/auth.rb +52 -0
- data/lib/securial/error/base_securial_error.rb +51 -0
- data/lib/securial/error/config.rb +33 -0
- data/lib/securial/error.rb +33 -3
- data/lib/securial/helpers/key_transformer.rb +106 -0
- data/lib/securial/helpers/normalizing_helper.rb +69 -0
- data/lib/securial/helpers/regex_helper.rb +122 -0
- data/lib/securial/helpers/roles_helper.rb +71 -2
- data/lib/securial/helpers.rb +48 -4
- data/lib/securial/logger/broadcaster.rb +89 -1
- data/lib/securial/logger/builder.rb +54 -1
- data/lib/securial/logger/formatter.rb +73 -0
- data/lib/securial/logger.rb +42 -1
- data/lib/securial/middleware/request_tag_logger.rb +80 -0
- data/lib/securial/middleware/response_headers.rb +51 -3
- data/lib/securial/middleware/transform_request_keys.rb +143 -20
- data/lib/securial/middleware/transform_response_keys.rb +84 -4
- data/lib/securial/middleware.rb +40 -9
- data/lib/securial/security/request_rate_limiter.rb +47 -1
- data/lib/securial/security.rb +37 -6
- data/lib/securial/version.rb +8 -1
- data/lib/securial.rb +36 -0
- 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
|
-
#
|
4
|
-
#
|
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 }
|
data/lib/securial/middleware.rb
CHANGED
@@ -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
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
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
|
-
[{
|
85
|
+
[{ errors: [resp_message] }.to_json],
|
40
86
|
]
|
41
87
|
end
|
42
88
|
end
|
data/lib/securial/security.rb
CHANGED
@@ -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
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
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
|
data/lib/securial/version.rb
CHANGED
@@ -1,3 +1,10 @@
|
|
1
1
|
module Securial
|
2
|
-
|
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.
|
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-
|
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
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
-
|
222
|
-
|
223
|
-
\
|
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
|