propel_authentication 0.1.2 → 0.1.4
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 +87 -0
- data/README.md +251 -113
- data/lib/generators/{propel_auth → propel_authentication}/install_generator.rb +89 -93
- data/lib/generators/{propel_auth → propel_authentication}/templates/auth_mailer.rb +1 -1
- data/lib/generators/{propel_auth → propel_authentication}/templates/authenticatable.rb +3 -3
- data/lib/generators/{propel_auth → propel_authentication}/templates/concerns/confirmable.rb +2 -2
- data/lib/generators/{propel_auth → propel_authentication}/templates/concerns/lockable.rb +6 -6
- data/lib/generators/{propel_auth → propel_authentication}/templates/concerns/recoverable.rb +6 -6
- data/lib/generators/propel_authentication/templates/core/configuration_methods.rb +151 -0
- data/lib/generators/{propel_auth → propel_authentication}/templates/invitation.rb +2 -2
- data/lib/generators/{propel_auth/templates/propel_auth.rb → propel_authentication/templates/propel_authentication.rb.tt} +18 -17
- data/lib/generators/{propel_auth → propel_authentication}/templates/test/concerns/lockable_test.rb.tt +12 -12
- data/lib/generators/{propel_auth → propel_authentication}/templates/test/concerns/propel_authentication_test.rb.tt +1 -1
- data/lib/generators/{propel_auth → propel_authentication}/templates/test/concerns/recoverable_test.rb.tt +7 -7
- data/lib/generators/{propel_auth → propel_authentication}/templates/user_test.rb.tt +1 -1
- data/lib/generators/{propel_auth → propel_authentication}/unpack_generator.rb +38 -25
- data/lib/propel_authentication.rb +3 -0
- metadata +98 -99
- data/lib/generators/propel_auth/pack_generator.rb +0 -277
- data/lib/generators/propel_auth/templates/lib/propel_auth.rb +0 -84
- data/lib/generators/propel_auth/test/dummy/Gemfile.lock +0 -394
- data/lib/propel_auth.rb +0 -3
- /data/lib/generators/{propel_auth → propel_authentication}/templates/agency.rb +0 -0
- /data/lib/generators/{propel_auth → propel_authentication}/templates/agent.rb +0 -0
- /data/lib/generators/{propel_auth → propel_authentication}/templates/auth/base_passwords_controller.rb.tt +0 -0
- /data/lib/generators/{propel_auth → propel_authentication}/templates/auth/base_tokens_controller.rb.tt +0 -0
- /data/lib/generators/{propel_auth → propel_authentication}/templates/auth/passwords_controller.rb.tt +0 -0
- /data/lib/generators/{propel_auth → propel_authentication}/templates/concerns/propel_authentication.rb +0 -0
- /data/lib/generators/{propel_auth → propel_authentication}/templates/concerns/rack_session_disable.rb +0 -0
- /data/lib/generators/{propel_auth → propel_authentication}/templates/config/environments/development_email.rb +0 -0
- /data/lib/generators/{propel_auth → propel_authentication}/templates/db/migrate/create_agencies.rb +0 -0
- /data/lib/generators/{propel_auth → propel_authentication}/templates/db/migrate/create_agents.rb +0 -0
- /data/lib/generators/{propel_auth → propel_authentication}/templates/db/migrate/create_invitations.rb +0 -0
- /data/lib/generators/{propel_auth → propel_authentication}/templates/db/migrate/create_organizations.rb +0 -0
- /data/lib/generators/{propel_auth → propel_authentication}/templates/db/migrate/create_users.rb +0 -0
- /data/lib/generators/{propel_auth → propel_authentication}/templates/db/seeds.rb +0 -0
- /data/lib/generators/{propel_auth → propel_authentication}/templates/organization.rb +0 -0
- /data/lib/generators/{propel_auth → propel_authentication}/templates/services/auth_notification_service.rb +0 -0
- /data/lib/generators/{propel_auth → propel_authentication}/templates/test/concerns/confirmable_test.rb.tt +0 -0
- /data/lib/generators/{propel_auth → propel_authentication}/templates/test/controllers/auth/lockable_integration_test.rb.tt +0 -0
- /data/lib/generators/{propel_auth → propel_authentication}/templates/test/controllers/auth/password_reset_integration_test.rb.tt +0 -0
- /data/lib/generators/{propel_auth → propel_authentication}/templates/test/controllers/auth/tokens_controller_test.rb.tt +0 -0
- /data/lib/generators/{propel_auth → propel_authentication}/templates/test/mailers/auth_mailer_test.rb.tt +0 -0
- /data/lib/generators/{propel_auth → propel_authentication}/templates/test/mailers/previews/auth_mailer_preview.rb +0 -0
- /data/lib/generators/{propel_auth → propel_authentication}/templates/tokens_controller.rb.tt +0 -0
- /data/lib/generators/{propel_auth → propel_authentication}/templates/user.rb +0 -0
- /data/lib/generators/{propel_auth → propel_authentication}/templates/views/auth_mailer/account_unlock.html.erb +0 -0
- /data/lib/generators/{propel_auth → propel_authentication}/templates/views/auth_mailer/account_unlock.text.erb +0 -0
- /data/lib/generators/{propel_auth → propel_authentication}/templates/views/auth_mailer/email_confirmation.html.erb +0 -0
- /data/lib/generators/{propel_auth → propel_authentication}/templates/views/auth_mailer/email_confirmation.text.erb +0 -0
- /data/lib/generators/{propel_auth → propel_authentication}/templates/views/auth_mailer/password_reset.html.erb +0 -0
- /data/lib/generators/{propel_auth → propel_authentication}/templates/views/auth_mailer/password_reset.text.erb +0 -0
- /data/lib/generators/{propel_auth → propel_authentication}/templates/views/auth_mailer/user_invitation.html.erb +0 -0
- /data/lib/generators/{propel_auth → propel_authentication}/templates/views/auth_mailer/user_invitation.text.erb +0 -0
- /data/lib/generators/{propel_auth → propel_authentication}/test/dummy/Dockerfile +0 -0
- /data/lib/generators/{propel_auth → propel_authentication}/test/dummy/Gemfile +0 -0
- /data/lib/generators/{propel_auth → propel_authentication}/test/dummy/README.md +0 -0
- /data/lib/generators/{propel_auth → propel_authentication}/test/dummy/Rakefile +0 -0
- /data/lib/generators/{propel_auth → propel_authentication}/test/dummy/app/assets/stylesheets/application.css +0 -0
- /data/lib/generators/{propel_auth → propel_authentication}/test/dummy/app/controllers/application_controller.rb +0 -0
- /data/lib/generators/{propel_auth → propel_authentication}/test/dummy/app/helpers/application_helper.rb +0 -0
- /data/lib/generators/{propel_auth → propel_authentication}/test/dummy/app/jobs/application_job.rb +0 -0
- /data/lib/generators/{propel_auth → propel_authentication}/test/dummy/app/mailers/application_mailer.rb +0 -0
- /data/lib/generators/{propel_auth → propel_authentication}/test/dummy/app/models/application_record.rb +0 -0
- /data/lib/generators/{propel_auth → propel_authentication}/test/dummy/app/views/layouts/application.html.erb +0 -0
- /data/lib/generators/{propel_auth → propel_authentication}/test/dummy/app/views/layouts/mailer.html.erb +0 -0
- /data/lib/generators/{propel_auth → propel_authentication}/test/dummy/app/views/layouts/mailer.text.erb +0 -0
- /data/lib/generators/{propel_auth → propel_authentication}/test/dummy/app/views/pwa/manifest.json.erb +0 -0
- /data/lib/generators/{propel_auth → propel_authentication}/test/dummy/app/views/pwa/service-worker.js +0 -0
- /data/lib/generators/{propel_auth → propel_authentication}/test/dummy/bin/brakeman +0 -0
- /data/lib/generators/{propel_auth → propel_authentication}/test/dummy/bin/dev +0 -0
- /data/lib/generators/{propel_auth → propel_authentication}/test/dummy/bin/docker-entrypoint +0 -0
- /data/lib/generators/{propel_auth → propel_authentication}/test/dummy/bin/rails +0 -0
- /data/lib/generators/{propel_auth → propel_authentication}/test/dummy/bin/rake +0 -0
- /data/lib/generators/{propel_auth → propel_authentication}/test/dummy/bin/rubocop +0 -0
- /data/lib/generators/{propel_auth → propel_authentication}/test/dummy/bin/setup +0 -0
- /data/lib/generators/{propel_auth → propel_authentication}/test/dummy/bin/thrust +0 -0
- /data/lib/generators/{propel_auth → propel_authentication}/test/dummy/config/application.rb +0 -0
- /data/lib/generators/{propel_auth → propel_authentication}/test/dummy/config/boot.rb +0 -0
- /data/lib/generators/{propel_auth → propel_authentication}/test/dummy/config/cable.yml +0 -0
- /data/lib/generators/{propel_auth → propel_authentication}/test/dummy/config/credentials.yml.enc +0 -0
- /data/lib/generators/{propel_auth → propel_authentication}/test/dummy/config/database.yml +0 -0
- /data/lib/generators/{propel_auth → propel_authentication}/test/dummy/config/environment.rb +0 -0
- /data/lib/generators/{propel_auth → propel_authentication}/test/dummy/config/environments/development.rb +0 -0
- /data/lib/generators/{propel_auth → propel_authentication}/test/dummy/config/environments/production.rb +0 -0
- /data/lib/generators/{propel_auth → propel_authentication}/test/dummy/config/environments/test.rb +0 -0
- /data/lib/generators/{propel_auth → propel_authentication}/test/dummy/config/initializers/assets.rb +0 -0
- /data/lib/generators/{propel_auth → propel_authentication}/test/dummy/config/initializers/content_security_policy.rb +0 -0
- /data/lib/generators/{propel_auth → propel_authentication}/test/dummy/config/initializers/filter_parameter_logging.rb +0 -0
- /data/lib/generators/{propel_auth → propel_authentication}/test/dummy/config/initializers/inflections.rb +0 -0
- /data/lib/generators/{propel_auth → propel_authentication}/test/dummy/config/locales/en.yml +0 -0
- /data/lib/generators/{propel_auth → propel_authentication}/test/dummy/config/master.key +0 -0
- /data/lib/generators/{propel_auth → propel_authentication}/test/dummy/config/puma.rb +0 -0
- /data/lib/generators/{propel_auth → propel_authentication}/test/dummy/config/routes.rb +0 -0
- /data/lib/generators/{propel_auth → propel_authentication}/test/dummy/config/storage.yml +0 -0
- /data/lib/generators/{propel_auth → propel_authentication}/test/dummy/config.ru +0 -0
- /data/lib/generators/{propel_auth → propel_authentication}/test/dummy/db/schema.rb +0 -0
- /data/lib/generators/{propel_auth → propel_authentication}/test/generators/authentication/controllers/tokens_controller_test.rb +0 -0
- /data/lib/generators/{propel_auth → propel_authentication}/test/generators/authentication/install_generator_test.rb +0 -0
- /data/lib/generators/{propel_auth → propel_authentication}/test/generators/authentication/uninstall_generator_test.rb +0 -0
- /data/lib/generators/{propel_auth → propel_authentication}/test/integration/generator_integration_test.rb +0 -0
- /data/lib/generators/{propel_auth → propel_authentication}/test/integration/multi_version_generator_test.rb +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6b1f57ecf3f4af5949e584a1a3999763ba8bbf5b558bfb0bbd8505de249c2603
|
4
|
+
data.tar.gz: d83ba00e83a944dfafac07fadc250cded1c6ba631108d91e5cd46c13c8592703
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a8fcdcbd5e287c80e989d9c7ebca67ca43b2eb5ee894aa330de5c3bbb1e08c25776837d24345b3c96bd04055cd960a8b433dd79dc912f1b316bec0a0fb45cf1e
|
7
|
+
data.tar.gz: f90e403196ba6e4df6adae2359331fbb82354b890ed8b2594d702d24f19318d65ad0e87d498530bd9848ced16a490fc6f5e006221a08f68539c364e12f17aeef
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,87 @@
|
|
1
|
+
# Changelog
|
2
|
+
|
3
|
+
All notable changes to this project will be documented in this file.
|
4
|
+
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
7
|
+
|
8
|
+
## [Unreleased]
|
9
|
+
|
10
|
+
### Planned Features
|
11
|
+
- OAuth provider integration (Google, GitHub, etc.)
|
12
|
+
- Two-factor authentication (TOTP)
|
13
|
+
- Session management and device tracking
|
14
|
+
- Advanced password policies
|
15
|
+
|
16
|
+
## [0.1.4] - 2025-01-23
|
17
|
+
|
18
|
+
### Fixed
|
19
|
+
- **Critical generator extraction issue** - Core infrastructure files now properly extracted during installation
|
20
|
+
- Fixed `require_relative 'core/configuration_methods'` LoadError
|
21
|
+
- Enhanced unpack generator to include all necessary infrastructure
|
22
|
+
- Complete "no black box" policy implementation
|
23
|
+
- **JWT authentication system** - Comprehensive fixes and improvements
|
24
|
+
- Proper JWT secret configuration using Rails secret_key_base
|
25
|
+
- Fixed token expiration error messages
|
26
|
+
- Improved parameter validation with Rails conventions (before_action)
|
27
|
+
- ActionCable configuration for test environment
|
28
|
+
- **Test suite** - All authentication tests now passing (11/11 - 100% success)
|
29
|
+
- Fixed fixture data foreign key constraints
|
30
|
+
- Proper multi-tenant JWT token verification
|
31
|
+
- Real database operations (no mocks) for confidence in production
|
32
|
+
|
33
|
+
### Added
|
34
|
+
- **Standalone operation** - Complete extraction of all authentication functionality
|
35
|
+
- All runtime code extracted to host application
|
36
|
+
- Zero gem dependencies after installation
|
37
|
+
- Full customization control for developers
|
38
|
+
|
39
|
+
### Improved
|
40
|
+
- **Rails conventions** - Better adherence to Rails patterns
|
41
|
+
- Clean before_action callbacks for parameter validation
|
42
|
+
- Proper error handling and status codes
|
43
|
+
- Enhanced test coverage with behavior-driven assertions
|
44
|
+
|
45
|
+
## [0.1.3] - 2025-01-XX
|
46
|
+
|
47
|
+
### Added
|
48
|
+
- **Self-extracting generator gem architecture** - Install temporarily, extract code, remove dependency
|
49
|
+
- **JWT-based authentication system** with complete feature set:
|
50
|
+
- User registration and login
|
51
|
+
- Password reset with email notifications
|
52
|
+
- Account lockout after failed attempts
|
53
|
+
- Email confirmation system
|
54
|
+
- Multi-tenant organization support
|
55
|
+
- **Rails generator system** with install and unpack commands
|
56
|
+
- **Complete authentication infrastructure**:
|
57
|
+
- User, Organization, and Agency models
|
58
|
+
- Authentication controllers with full CRUD
|
59
|
+
- Email templates for notifications
|
60
|
+
- Comprehensive test suite
|
61
|
+
- Database migrations and seeds
|
62
|
+
|
63
|
+
### Features
|
64
|
+
- **JWT token management** with configurable expiration
|
65
|
+
- **Multi-tenant architecture** with organization-based isolation
|
66
|
+
- **Email notifications** for password reset and account actions
|
67
|
+
- **Account security** with lockout and unlock mechanisms
|
68
|
+
- **Flexible configuration** system for all authentication settings
|
69
|
+
- **Production-ready** with comprehensive error handling
|
70
|
+
|
71
|
+
### Technical Implementation
|
72
|
+
- Clean generator architecture following Rails conventions
|
73
|
+
- Template-based code generation for easy customization
|
74
|
+
- Proper Ruby module structure with namespace isolation
|
75
|
+
- Comprehensive test suite with real database operations
|
76
|
+
- Zero runtime dependencies after code extraction
|
77
|
+
|
78
|
+
### Generator Commands
|
79
|
+
- `rails generate propel_authentication:install` - Install authentication system
|
80
|
+
- `rails generate propel_authentication:unpack` - Extract generator for customization
|
81
|
+
- Selective unpacking with component-specific options
|
82
|
+
|
83
|
+
### Self-Extracting Benefits
|
84
|
+
- **No runtime gem dependencies** - all code lives in host application
|
85
|
+
- **Full customization control** - modify any authentication component
|
86
|
+
- **Standard Rails patterns** - follows established conventions
|
87
|
+
- **Easy maintenance** - no hidden gem complexity in production
|
data/README.md
CHANGED
@@ -1,16 +1,16 @@
|
|
1
|
-
#
|
1
|
+
# PropelAuthentication
|
2
2
|
|
3
|
-
A comprehensive Rails generator that creates a complete JWT-based authentication system with
|
3
|
+
A comprehensive Rails generator that creates a complete JWT-based authentication system with multi-tenant organization structure, user management, password security, and email notifications.
|
4
4
|
|
5
5
|
## Installation
|
6
6
|
|
7
|
-
|
7
|
+
PropelAuthentication is designed as a **self-extracting generator gem** following the "no black box" policy. You install it temporarily, run the generators to extract all code into your application, then optionally remove the gem dependency.
|
8
8
|
|
9
|
-
### Step 1: Add to Gemfile
|
9
|
+
### Step 1: Add to Gemfile
|
10
10
|
|
11
11
|
```ruby
|
12
12
|
# In your Gemfile
|
13
|
-
gem '
|
13
|
+
gem 'propel_authentication', '~> 0.1.4'
|
14
14
|
```
|
15
15
|
|
16
16
|
### Step 2: Bundle Install
|
@@ -19,27 +19,23 @@ gem 'propel_auth', path: 'propel_auth'
|
|
19
19
|
bundle install
|
20
20
|
```
|
21
21
|
|
22
|
-
### Step 3:
|
23
|
-
|
24
|
-
If you want to customize the generator templates:
|
22
|
+
### Step 3: Install PropelAuthentication
|
25
23
|
|
26
24
|
```bash
|
27
|
-
rails generate
|
25
|
+
rails generate propel_authentication:install
|
28
26
|
```
|
29
27
|
|
30
|
-
This
|
28
|
+
This installs the complete authentication system including models, controllers, services, mailers, and tests.
|
31
29
|
|
32
|
-
### Step 4:
|
30
|
+
### Step 4: Run Migrations
|
33
31
|
|
34
32
|
```bash
|
35
|
-
rails
|
33
|
+
rails db:migrate
|
36
34
|
```
|
37
35
|
|
38
|
-
This installs the complete authentication system including models, controllers, services, and mailers.
|
39
|
-
|
40
36
|
### Step 5: Remove Gem Dependency (Optional)
|
41
37
|
|
42
|
-
After installation, you can remove the gem from your Gemfile. All functionality remains in your application.
|
38
|
+
After installation, you can remove the gem from your Gemfile. All functionality remains in your application as extracted code.
|
43
39
|
|
44
40
|
## Usage
|
45
41
|
|
@@ -47,45 +43,77 @@ After installation, you can remove the gem from your Gemfile. All functionality
|
|
47
43
|
|
48
44
|
The generator creates a complete authentication system with:
|
49
45
|
|
50
|
-
- **User model** - Primary user accounts with authentication
|
46
|
+
- **User model** - Primary user accounts with JWT authentication
|
51
47
|
- **Organization model** - Multi-tenant organization structure
|
52
|
-
- **Agency model** - Intermediate organization management
|
53
|
-
- **Agent model** -
|
54
|
-
- **Invitation model** - User invitation system
|
55
|
-
- **Authentication controllers** - Login, logout, token management
|
56
|
-
- **
|
57
|
-
- **
|
58
|
-
- **Account locking** - Security protection against brute force
|
59
|
-
- **Auth mailer** - Email notifications for auth events
|
60
|
-
- **Auth service** - Centralized authentication logic
|
48
|
+
- **Agency model** - Intermediate organization management layer
|
49
|
+
- **Agent model** - Agent user accounts within agencies
|
50
|
+
- **Invitation model** - User invitation and onboarding system
|
51
|
+
- **Authentication controllers** - Login, logout, token management, password reset
|
52
|
+
- **Email system** - Password reset, account unlock, and invitation emails
|
53
|
+
- **Security features** - Account locking, password validation, JWT tokens
|
61
54
|
|
62
55
|
### Authentication Flow
|
63
56
|
|
64
|
-
```
|
57
|
+
```bash
|
65
58
|
# Login
|
66
|
-
POST /
|
59
|
+
POST /login
|
60
|
+
Content-Type: application/json
|
61
|
+
|
67
62
|
{
|
68
|
-
"
|
69
|
-
|
63
|
+
"user": {
|
64
|
+
"email_address": "user@example.com",
|
65
|
+
"password": "password"
|
66
|
+
}
|
70
67
|
}
|
71
68
|
|
72
69
|
# Response
|
73
70
|
{
|
74
|
-
"
|
75
|
-
|
76
|
-
"
|
77
|
-
"
|
71
|
+
"token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...",
|
72
|
+
"user": {
|
73
|
+
"id": 1,
|
74
|
+
"email_address": "user@example.com",
|
75
|
+
"first_name": "John",
|
76
|
+
"last_name": "Doe",
|
77
|
+
"organization": {
|
78
|
+
"id": 1,
|
79
|
+
"name": "Acme Corp"
|
80
|
+
}
|
78
81
|
}
|
79
82
|
}
|
80
83
|
|
81
84
|
# Access protected resources
|
82
85
|
GET /api/v1/protected_resource
|
83
86
|
Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...
|
87
|
+
|
88
|
+
# Get current user info
|
89
|
+
GET /me
|
90
|
+
Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...
|
91
|
+
|
92
|
+
# Logout (client-side token removal)
|
93
|
+
DELETE /logout
|
94
|
+
Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...
|
95
|
+
```
|
96
|
+
|
97
|
+
### Authentication Routes
|
98
|
+
|
99
|
+
The system generates these authentication routes:
|
100
|
+
|
101
|
+
```ruby
|
102
|
+
# JWT Authentication routes
|
103
|
+
post 'login', to: 'auth/tokens#create'
|
104
|
+
get 'me', to: 'auth/tokens#me'
|
105
|
+
delete 'logout', to: 'auth/tokens#destroy'
|
106
|
+
post 'unlock', to: 'auth/tokens#unlock'
|
107
|
+
|
108
|
+
# Password reset routes
|
109
|
+
post 'reset', to: 'auth/passwords#create'
|
110
|
+
get 'reset', to: 'auth/passwords#show'
|
111
|
+
patch 'reset', to: 'auth/passwords#update'
|
84
112
|
```
|
85
113
|
|
86
114
|
### Authentication Concerns
|
87
115
|
|
88
|
-
|
116
|
+
PropelAuthentication generates reusable concerns for models and controllers:
|
89
117
|
|
90
118
|
```ruby
|
91
119
|
# In your models
|
@@ -93,7 +121,7 @@ class User < ApplicationRecord
|
|
93
121
|
include Authenticatable # JWT token generation and validation
|
94
122
|
include Lockable # Account locking after failed attempts
|
95
123
|
include Recoverable # Password reset functionality
|
96
|
-
include Confirmable # Email confirmation
|
124
|
+
include Confirmable # Email confirmation (future feature)
|
97
125
|
|
98
126
|
# Your model customizations here
|
99
127
|
end
|
@@ -101,19 +129,24 @@ end
|
|
101
129
|
# In your controllers
|
102
130
|
class ApplicationController < ActionController::API
|
103
131
|
include PropelAuthentication # Authentication helpers
|
104
|
-
include RackSessionDisable # Disable Rails sessions for API
|
132
|
+
include RackSessionDisable # Disable Rails sessions for API-only apps
|
133
|
+
|
134
|
+
# Use authenticate_user to protect endpoints
|
135
|
+
before_action :authenticate_user, except: [:public_endpoint]
|
105
136
|
end
|
106
137
|
```
|
107
138
|
|
108
139
|
### Password Reset Flow
|
109
140
|
|
110
|
-
```
|
141
|
+
```bash
|
111
142
|
# Request password reset
|
112
|
-
POST /
|
113
|
-
{
|
143
|
+
POST /reset
|
144
|
+
{
|
145
|
+
"email_address": "user@example.com"
|
146
|
+
}
|
114
147
|
|
115
|
-
# Reset password with token
|
116
|
-
PATCH /
|
148
|
+
# Reset password with token (from email)
|
149
|
+
PATCH /reset
|
117
150
|
{
|
118
151
|
"token": "reset_token_from_email",
|
119
152
|
"password": "new_password",
|
@@ -121,46 +154,50 @@ PATCH /auth/passwords
|
|
121
154
|
}
|
122
155
|
```
|
123
156
|
|
124
|
-
### Account Features
|
157
|
+
### Account Security Features
|
125
158
|
|
126
|
-
- **
|
127
|
-
- **Account
|
128
|
-
- **Password
|
129
|
-
- **
|
130
|
-
- **Multi-tenancy** - Organization-based
|
159
|
+
- **JWT Authentication** - Stateless, secure token-based authentication
|
160
|
+
- **Account Locking** - Automatic lockout after failed login attempts
|
161
|
+
- **Password Security** - BCrypt hashing with configurable requirements
|
162
|
+
- **Password Reset** - Secure token-based password reset via email
|
163
|
+
- **Multi-tenancy** - Organization-based user isolation
|
164
|
+
- **Email Notifications** - Automated emails for security events
|
131
165
|
|
132
166
|
## Features
|
133
167
|
|
134
168
|
### Complete Authentication System
|
135
169
|
- **JWT-based authentication** - Stateless, scalable token system
|
136
170
|
- **Multi-tenant architecture** - User/Organization/Agency/Agent model hierarchy
|
137
|
-
- **
|
138
|
-
- **Password security** - Reset, expiration, and strength requirements
|
171
|
+
- **Password security** - BCrypt hashing, reset functionality, strength requirements
|
139
172
|
- **Account protection** - Automatic locking and unlock mechanisms
|
140
|
-
- **
|
173
|
+
- **Email notifications** - Password reset, account unlock, user invitations
|
174
|
+
- **Invitation system** - Complete user invitation and onboarding workflow
|
141
175
|
|
142
176
|
### Production-Ready Security
|
143
177
|
- **BCrypt password hashing** - Industry standard password protection
|
144
|
-
- **JWT token validation** - Secure token-based authentication
|
145
|
-
- **
|
146
|
-
- **
|
147
|
-
- **
|
178
|
+
- **JWT token validation** - Secure token-based authentication with configurable expiration
|
179
|
+
- **Account lockout protection** - Configurable failed attempt limits and lockout duration
|
180
|
+
- **Rate limiting ready** - Designed for integration with rate limiting systems
|
181
|
+
- **Secure token generation** - Cryptographically secure tokens for password reset
|
182
|
+
- **Environment-specific configuration** - Different security settings per environment
|
148
183
|
|
149
184
|
### Rails Integration
|
150
185
|
- **Standard Rails patterns** - Follows Rails conventions throughout
|
151
186
|
- **ActiveRecord models** - Standard model associations and validations
|
152
|
-
- **ActionMailer integration** - Built-in email functionality
|
187
|
+
- **ActionMailer integration** - Built-in email functionality with templates
|
153
188
|
- **Controller concerns** - Reusable authentication logic
|
154
|
-
- **
|
189
|
+
- **Comprehensive testing** - Complete test suite included
|
190
|
+
- **Migration support** - Database schema with proper indexes
|
155
191
|
|
156
192
|
## Self-Extracting Architecture
|
157
193
|
|
158
|
-
|
194
|
+
PropelAuthentication follows a "no black box" self-extracting pattern:
|
159
195
|
|
160
|
-
- **
|
161
|
-
- **
|
162
|
-
- **
|
163
|
-
- **
|
196
|
+
- **Complete code extraction** - All functionality copied to your application
|
197
|
+
- **No runtime dependencies** - Remove the gem after installation
|
198
|
+
- **Full customization** - Modify any component after installation
|
199
|
+
- **Transparent implementation** - Readable, standard Rails code
|
200
|
+
- **Generator extraction** - Optionally extract generator templates for customization
|
164
201
|
|
165
202
|
After installation, you can:
|
166
203
|
- Remove the gem from your Gemfile
|
@@ -170,18 +207,23 @@ After installation, you can:
|
|
170
207
|
|
171
208
|
## Configuration
|
172
209
|
|
173
|
-
Configure
|
210
|
+
Configure PropelAuthentication in the generated `config/initializers/propel_authentication.rb`:
|
174
211
|
|
175
212
|
```ruby
|
176
|
-
|
213
|
+
PropelAuthentication.configure do |config|
|
177
214
|
# JWT Configuration
|
178
|
-
config.jwt_secret = Rails.application.
|
179
|
-
|
215
|
+
config.jwt_secret = Rails.application.config.secret_key_base ||
|
216
|
+
Rails.application.credentials.secret_key_base ||
|
217
|
+
ENV['SECRET_KEY_BASE']
|
218
|
+
config.jwt_expiration = Rails.env.production? ? 2.hours : 24.hours
|
180
219
|
config.jwt_algorithm = 'HS256'
|
181
220
|
|
182
221
|
# Password requirements
|
183
222
|
config.password_length = 8..128
|
184
223
|
|
224
|
+
# User registration settings
|
225
|
+
config.allow_registration = true
|
226
|
+
|
185
227
|
# Account lockout settings
|
186
228
|
config.max_failed_attempts = 10
|
187
229
|
config.lockout_duration = 30.minutes
|
@@ -191,86 +233,144 @@ PropelAuth.configure do |config|
|
|
191
233
|
config.password_reset_rate_limit = 1.minute
|
192
234
|
|
193
235
|
# Email settings
|
194
|
-
config.frontend_url = 'http://localhost:3000'
|
195
|
-
config.email_from_address = "noreply
|
236
|
+
config.frontend_url = Rails.env.development? ? 'http://localhost:3000' : 'https://yourapp.com'
|
237
|
+
config.email_from_address = "noreply@yourapp.com"
|
238
|
+
config.support_email = "support@yourapp.com"
|
196
239
|
config.enable_email_notifications = true
|
197
240
|
end
|
198
241
|
```
|
199
242
|
|
200
243
|
## Generated Files
|
201
244
|
|
202
|
-
After installation,
|
245
|
+
After installation, PropelAuthentication creates:
|
203
246
|
|
204
247
|
### Models
|
205
|
-
- `app/models/user.rb` - Primary user model
|
206
|
-
- `app/models/organization.rb` -
|
207
|
-
- `app/models/agency.rb` - Agency management
|
248
|
+
- `app/models/user.rb` - Primary user model with authentication
|
249
|
+
- `app/models/organization.rb` - Multi-tenant organization model
|
250
|
+
- `app/models/agency.rb` - Agency management within organizations
|
208
251
|
- `app/models/agent.rb` - Agent user accounts
|
209
252
|
- `app/models/invitation.rb` - User invitation system
|
210
253
|
- `app/models/concerns/authenticatable.rb` - JWT authentication logic
|
211
|
-
- `app/models/concerns/confirmable.rb` - Email confirmation
|
212
|
-
- `app/models/concerns/lockable.rb` - Account locking
|
213
|
-
- `app/models/concerns/recoverable.rb` - Password recovery
|
254
|
+
- `app/models/concerns/confirmable.rb` - Email confirmation (future feature)
|
255
|
+
- `app/models/concerns/lockable.rb` - Account locking functionality
|
256
|
+
- `app/models/concerns/recoverable.rb` - Password recovery logic
|
214
257
|
|
215
258
|
### Controllers
|
216
|
-
- `app/controllers/auth/tokens_controller.rb` - Login
|
217
|
-
- `app/controllers/auth/passwords_controller.rb` - Password reset
|
259
|
+
- `app/controllers/auth/tokens_controller.rb` - Login, logout, user info
|
260
|
+
- `app/controllers/auth/passwords_controller.rb` - Password reset functionality
|
218
261
|
- `app/controllers/concerns/propel_authentication.rb` - Authentication helpers
|
219
|
-
- `app/controllers/concerns/rack_session_disable.rb` - Session management
|
262
|
+
- `app/controllers/concerns/rack_session_disable.rb` - Session management for APIs
|
220
263
|
|
221
264
|
### Services
|
222
|
-
- `app/services/auth_notification_service.rb` - Email
|
223
|
-
|
224
|
-
### Mailers
|
225
|
-
- `app/mailers/auth_mailer.rb` - Authentication
|
226
|
-
- `app/views/auth_mailer
|
227
|
-
|
228
|
-
|
265
|
+
- `app/services/auth_notification_service.rb` - Email notification service
|
266
|
+
|
267
|
+
### Mailers and Views
|
268
|
+
- `app/mailers/auth_mailer.rb` - Authentication email mailer
|
269
|
+
- `app/views/auth_mailer/password_reset.html.erb` - Password reset email template
|
270
|
+
- `app/views/auth_mailer/password_reset.text.erb` - Text version
|
271
|
+
- `app/views/auth_mailer/account_unlock.html.erb` - Account unlock email template
|
272
|
+
- `app/views/auth_mailer/account_unlock.text.erb` - Text version
|
273
|
+
- `app/views/auth_mailer/user_invitation.html.erb` - User invitation email template
|
274
|
+
- `app/views/auth_mailer/user_invitation.text.erb` - Text version
|
275
|
+
- `app/views/auth_mailer/email_confirmation.html.erb` - Email confirmation template
|
276
|
+
- `app/views/auth_mailer/email_confirmation.text.erb` - Text version
|
277
|
+
|
278
|
+
### Database Migrations
|
229
279
|
- User, Organization, Agency, Agent, and Invitation table creation
|
230
|
-
- Authentication-related fields
|
280
|
+
- Authentication-related fields (password_digest, failed_attempts, locked_at, etc.)
|
281
|
+
- Proper indexes for performance
|
282
|
+
- Foreign key relationships
|
231
283
|
|
232
284
|
### Tests
|
233
|
-
-
|
234
|
-
-
|
235
|
-
-
|
236
|
-
-
|
285
|
+
- `test/models/user_test.rb` - User model tests
|
286
|
+
- `test/controllers/auth/tokens_controller_test.rb` - Authentication controller tests
|
287
|
+
- `test/mailers/auth_mailer_test.rb` - Email functionality tests
|
288
|
+
- `test/concerns/` - Tests for all authentication concerns
|
289
|
+
- `test/controllers/auth/` - Integration tests for authentication flows
|
290
|
+
- Complete fixture files for all models
|
237
291
|
|
238
|
-
### Configuration
|
239
|
-
- `config/initializers/
|
240
|
-
- `lib/
|
292
|
+
### Configuration and Runtime
|
293
|
+
- `config/initializers/propel_authentication.rb` - Configuration file
|
294
|
+
- `lib/propel_authentication.rb` - Complete runtime library (extracted from gem)
|
295
|
+
- `config/environments/development_email.rb` - Email configuration for development
|
241
296
|
|
242
|
-
##
|
297
|
+
## Advanced Usage
|
243
298
|
|
244
|
-
|
299
|
+
### Custom Authentication Logic
|
245
300
|
|
246
|
-
```
|
247
|
-
|
248
|
-
|
301
|
+
```ruby
|
302
|
+
class Api::V1::UsersController < ApplicationController
|
303
|
+
include PropelAuthentication
|
304
|
+
before_action :authenticate_user
|
305
|
+
|
306
|
+
def index
|
307
|
+
# current_user is available after authenticate_user
|
308
|
+
users = current_user.organization.users
|
309
|
+
render json: users
|
310
|
+
end
|
311
|
+
|
312
|
+
def show
|
313
|
+
# Access control based on organization
|
314
|
+
user = current_user.organization.users.find(params[:id])
|
315
|
+
render json: user
|
316
|
+
end
|
317
|
+
end
|
318
|
+
```
|
249
319
|
|
250
|
-
|
320
|
+
### Multi-Tenant Organization Structure
|
321
|
+
|
322
|
+
```ruby
|
323
|
+
# Users belong to organizations
|
324
|
+
user = User.find(1)
|
325
|
+
user.organization.name # => "Acme Corp"
|
326
|
+
|
327
|
+
# Organizations can have multiple agencies
|
328
|
+
organization = Organization.find(1)
|
329
|
+
organization.agencies.count # => 3
|
330
|
+
|
331
|
+
# Agencies have agents (specialized users)
|
332
|
+
agency = Agency.find(1)
|
333
|
+
agency.agents.active.count # => 5
|
251
334
|
```
|
252
335
|
|
253
|
-
|
336
|
+
### Email Customization
|
254
337
|
|
255
|
-
|
256
|
-
- **BCrypt ~> 3.1.20** - Secure password hashing
|
257
|
-
- **JWT ~> 2.7** - JSON Web Token authentication
|
338
|
+
All email templates are extracted to your application and can be customized:
|
258
339
|
|
259
|
-
|
340
|
+
```erb
|
341
|
+
<!-- app/views/auth_mailer/password_reset.html.erb -->
|
342
|
+
<h1>Password Reset Request</h1>
|
343
|
+
<p>Hello <%= @user.first_name %>,</p>
|
344
|
+
<p>You requested a password reset for your account.</p>
|
345
|
+
<p><%= link_to "Reset Password", @reset_url %></p>
|
346
|
+
```
|
260
347
|
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
bundle exec rake test
|
348
|
+
## Generator Customization
|
349
|
+
|
350
|
+
Extract generator templates for customization:
|
265
351
|
|
266
|
-
|
267
|
-
|
352
|
+
```bash
|
353
|
+
rails generate propel_authentication:unpack
|
268
354
|
```
|
269
355
|
|
270
|
-
|
356
|
+
This creates `lib/generators/propel_authentication/` with all templates, allowing you to:
|
357
|
+
- Modify model templates
|
358
|
+
- Customize controller logic
|
359
|
+
- Change email templates
|
360
|
+
- Adjust migration structure
|
271
361
|
|
272
|
-
|
362
|
+
## Dependencies
|
273
363
|
|
364
|
+
- **Rails 7.0+** - Modern Rails framework support
|
365
|
+
- **BCrypt ~> 3.1.20** - Secure password hashing
|
366
|
+
- **JWT ~> 2.7** - JSON Web Token authentication
|
367
|
+
- **Letter Opener** (development) - Email preview in development
|
368
|
+
|
369
|
+
## Integration with PropelRails Ecosystem
|
370
|
+
|
371
|
+
PropelAuthentication integrates seamlessly with other PropelRails gems:
|
372
|
+
|
373
|
+
### With PropelAPI
|
274
374
|
```ruby
|
275
375
|
# Generated API controllers automatically include authentication
|
276
376
|
class Api::V1::ApiController < ApplicationController
|
@@ -281,10 +381,48 @@ class Api::V1::ApiController < ApplicationController
|
|
281
381
|
end
|
282
382
|
```
|
283
383
|
|
384
|
+
### With PropelFacets
|
385
|
+
```ruby
|
386
|
+
# Use authentication with JSON facets
|
387
|
+
class Api::V1::UsersController < Api::V1::ApiController
|
388
|
+
def index
|
389
|
+
users = current_user.organization.users
|
390
|
+
render_facet users, :summary
|
391
|
+
end
|
392
|
+
end
|
393
|
+
```
|
394
|
+
|
395
|
+
## Development and Testing
|
396
|
+
|
397
|
+
```bash
|
398
|
+
# Run all authentication tests
|
399
|
+
rails test test/models/user_test.rb
|
400
|
+
rails test test/controllers/auth/
|
401
|
+
rails test test/concerns/
|
402
|
+
rails test test/mailers/
|
403
|
+
|
404
|
+
# Test specific authentication flows
|
405
|
+
rails test test/controllers/auth/tokens_controller_test.rb
|
406
|
+
rails test test/controllers/auth/password_reset_integration_test.rb
|
407
|
+
|
408
|
+
# Run generator tests (if gem is in development)
|
409
|
+
cd propel_authentication
|
410
|
+
bundle exec rake test
|
411
|
+
```
|
412
|
+
|
413
|
+
## Version History
|
414
|
+
|
415
|
+
### 0.1.4 (Current)
|
416
|
+
- Fixed generator extraction issues
|
417
|
+
- Enhanced JWT authentication with proper secret handling
|
418
|
+
- Complete test suite passing
|
419
|
+
- Improved "no black box" policy implementation
|
420
|
+
- Better integration with PropelRails ecosystem
|
421
|
+
|
284
422
|
## Contributing
|
285
423
|
|
286
|
-
Bug reports and pull requests are welcome on GitHub.
|
424
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/propel-web/propel_rails.
|
287
425
|
|
288
426
|
## License
|
289
427
|
|
290
|
-
The gem is available as open source under the [MIT License](https://opensource.org/licenses/MIT).
|
428
|
+
The gem is available as open source under the [MIT License](https://opensource.org/licenses/MIT).
|