PropelAuthentication
A comprehensive Rails generator that creates a complete JWT-based authentication system with multi-tenant organization structure, user management, password security, and email notifications.
Installation
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.
Step 1: Add to Gemfile
# In your Gemfile
gem 'propel_authentication', '~> 0.2.0'
Step 2: Bundle Install
bundle install
Step 3: Install PropelAuthentication
rails generate propel_authentication:install
This installs the complete authentication system including models, controllers, services, mailers, and tests.
Step 4: Run Migrations
rails db:migrate
Step 5: Remove Gem Dependency (Optional)
After installation, you can remove the gem from your Gemfile. All functionality remains in your application as extracted code.
Usage
Generated Authentication System
The generator creates a complete authentication system with:
- User model - Primary user accounts with JWT authentication
- Organization model - Multi-tenant organization structure
- Agency model - Intermediate organization management layer
- Agent model - Agent user accounts within agencies
- Invitation model - User invitation and onboarding system
- Authentication controllers - Login, logout, token management, password reset
- Email system - Password reset, account unlock, and invitation emails
- Security features - Account locking, password validation, JWT tokens
Authentication Flow
# Login
POST /login
Content-Type: application/json
{
"user": {
"email_address": "[email protected]",
"password": "password"
}
}
# Response
{
"token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...",
"user": {
"id": 1,
"email_address": "[email protected]",
"first_name": "John",
"last_name": "Doe",
"organization": {
"id": 1,
"name": "Acme Corp"
}
}
}
# Access protected resources
GET /api/v1/protected_resource
Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...
# Get current user info
GET /me
Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...
# Logout (client-side token removal)
DELETE /logout
Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...
Authentication Routes
The system generates these authentication routes:
# JWT Authentication routes
post 'login', to: 'auth/tokens#create'
get 'me', to: 'auth/tokens#me'
delete 'logout', to: 'auth/tokens#destroy'
post 'unlock', to: 'auth/tokens#unlock'
# Password reset routes
post 'reset', to: 'auth/passwords#create'
get 'reset', to: 'auth/passwords#show'
patch 'reset', to: 'auth/passwords#update'
Authentication Concerns
PropelAuthentication generates reusable concerns for models and controllers:
# In your models
class User < ApplicationRecord
include Authenticatable # JWT token generation and validation
include Lockable # Account locking after failed attempts
include Recoverable # Password reset functionality
include Confirmable # Email confirmation (future feature)
# Your model customizations here
end
# In your controllers
class ApplicationController < ActionController::API
include PropelAuthenticationConcernConcern # Authentication helpers
include RackSessionDisable # Disable Rails sessions for API-only apps
# Use authenticate_user to protect endpoints
before_action :authenticate_user, except: [:public_endpoint]
end
Password Reset Flow
# Request password reset
POST /reset
{
"email_address": "[email protected]"
}
# Reset password with token (from email)
PATCH /reset
{
"token": "reset_token_from_email",
"password": "new_password",
"password_confirmation": "new_password"
}
Account Security Features
- JWT Authentication - Stateless, secure token-based authentication
- Account Locking - Automatic lockout after failed login attempts
- Password Security - BCrypt hashing with configurable requirements
- Password Reset - Secure token-based password reset via email
- Multi-tenancy - Organization-based user isolation
- Email Notifications - Automated emails for security events
Features
Complete Authentication System
- JWT-based authentication - Stateless, scalable token system
- Multi-tenant architecture - User/Organization/Agency/Agent model hierarchy
- Password security - BCrypt hashing, reset functionality, strength requirements
- Account protection - Automatic locking and unlock mechanisms
- Email notifications - Password reset, account unlock, user invitations
- Invitation system - Complete user invitation and onboarding workflow
Production-Ready Security
- BCrypt password hashing - Industry standard password protection
- JWT token validation - Secure token-based authentication with configurable expiration
- Account lockout protection - Configurable failed attempt limits and lockout duration
- Rate limiting ready - Designed for integration with rate limiting systems
- Secure token generation - Cryptographically secure tokens for password reset
- Environment-specific configuration - Different security settings per environment
Rails Integration
- Standard Rails patterns - Follows Rails conventions throughout
- ActiveRecord models - Standard model associations and validations
- ActionMailer integration - Built-in email functionality with templates
- Controller concerns - Reusable authentication logic
- Comprehensive testing - Complete test suite included
- Migration support - Database schema with proper indexes
Self-Extracting Architecture
PropelAuthentication follows a "no black box" self-extracting pattern:
- Complete code extraction - All functionality copied to your application
- No runtime dependencies - Remove the gem after installation
- Full customization - Modify any component after installation
- Transparent implementation - Readable, standard Rails code
- Generator extraction - Optionally extract generator templates for customization
After installation, you can:
- Remove the gem from your Gemfile
- Customize all generated code
- Maintain and extend functionality independently
- Integrate with existing authentication systems
Configuration
Configure PropelAuthentication in the generated config/initializers/propel_authentication.rb
:
PropelAuthentication.configure do |config|
# JWT Configuration
config.jwt_secret = Rails.application.config.secret_key_base ||
Rails.application.credentials.secret_key_base ||
ENV['SECRET_KEY_BASE']
config.jwt_expiration = Rails.env.production? ? 2.hours : 24.hours
config.jwt_algorithm = 'HS256'
# Password requirements
config.password_length = 8..128
# User registration settings
config.allow_registration = true
# Account lockout settings
config.max_failed_attempts = 10
config.lockout_duration = 30.minutes
# Password reset settings
config.password_reset_expiration = 15.minutes
config.password_reset_rate_limit = 1.minute
# Email settings
config.frontend_url = Rails.env.development? ? 'http://localhost:3000' : 'https://yourapp.com'
config.email_from_address = "[email protected]"
config.support_email = "[email protected]"
config.enable_email_notifications = true
end
Generated Files
After installation, PropelAuthentication creates:
Models
app/models/user.rb
- Primary user model with authenticationapp/models/organization.rb
- Multi-tenant organization modelapp/models/agency.rb
- Agency management within organizationsapp/models/agent.rb
- Agent user accountsapp/models/invitation.rb
- User invitation systemapp/models/concerns/authenticatable.rb
- JWT authentication logicapp/models/concerns/confirmable.rb
- Email confirmation (future feature)app/models/concerns/lockable.rb
- Account locking functionalityapp/models/concerns/recoverable.rb
- Password recovery logic
Controllers
app/controllers/auth/tokens_controller.rb
- Login, logout, user infoapp/controllers/auth/passwords_controller.rb
- Password reset functionalityapp/controllers/concerns/propel_authentication_concern.rb
- Authentication helpersapp/controllers/concerns/rack_session_disable.rb
- Session management for APIs
Services
app/services/auth_notification_service.rb
- Email notification service
Mailers and Views
app/mailers/auth_mailer.rb
- Authentication email mailerapp/views/auth_mailer/password_reset.html.erb
- Password reset email templateapp/views/auth_mailer/password_reset.text.erb
- Text versionapp/views/auth_mailer/account_unlock.html.erb
- Account unlock email templateapp/views/auth_mailer/account_unlock.text.erb
- Text versionapp/views/auth_mailer/user_invitation.html.erb
- User invitation email templateapp/views/auth_mailer/user_invitation.text.erb
- Text versionapp/views/auth_mailer/email_confirmation.html.erb
- Email confirmation templateapp/views/auth_mailer/email_confirmation.text.erb
- Text version
Database Migrations
- User, Organization, Agency, Agent, and Invitation table creation
- Authentication-related fields (password_digest, failed_attempts, locked_at, etc.)
- Proper indexes for performance
- Foreign key relationships
Tests
test/models/user_test.rb
- User model teststest/controllers/auth/tokens_controller_test.rb
- Authentication controller teststest/mailers/auth_mailer_test.rb
- Email functionality teststest/concerns/
- Tests for all authentication concernstest/controllers/auth/
- Integration tests for authentication flows- Complete fixture files for all models
Configuration and Runtime
config/initializers/propel_authentication.rb
- Configuration filelib/propel_authentication.rb
- Complete runtime library (extracted from gem)config/environments/development_email.rb
- Email configuration for development
Advanced Usage
Custom Authentication Logic
class Api::V1::UsersController < ApplicationController
include PropelAuthenticationConcern
before_action :authenticate_user
def index
# current_user is available after authenticate_user
users = current_user.organization.users
render json: users
end
def show
# Access control based on organization
user = current_user.organization.users.find(params[:id])
render json: user
end
end
Multi-Tenant Organization Structure
# Users belong to organizations
user = User.find(1)
user.organization.name # => "Acme Corp"
# Organizations can have multiple agencies
organization = Organization.find(1)
organization.agencies.count # => 3
# Agencies have agents (specialized users)
agency = Agency.find(1)
agency.agents.active.count # => 5
Email Customization
All email templates are extracted to your application and can be customized:
<!-- app/views/auth_mailer/password_reset.html.erb -->
<h1>Password Reset Request</h1>
<p>Hello <%= @user.first_name %>,</p>
<p>You requested a password reset for your account.</p>
<p><%= link_to "Reset Password", @reset_url %></p>
Generator Customization
Extract generator templates for customization:
rails generate propel_authentication:unpack
This creates lib/generators/propel_authentication/
with all templates, allowing you to:
- Modify model templates
- Customize controller logic
- Change email templates
- Adjust migration structure
Dependencies
- Rails 7.0+ - Modern Rails framework support
- BCrypt ~> 3.1.20 - Secure password hashing
- JWT ~> 2.7 - JSON Web Token authentication
- Letter Opener (development) - Email preview in development
Integration with PropelRails Ecosystem
PropelAuthentication integrates seamlessly with other PropelRails gems:
With PropelAPI
# Generated API controllers automatically include authentication
class Api::V1::ApiController < ApplicationController
include PropelAuthenticationConcern
before_action :authenticate_user
# Your API methods here
end
With PropelFacets
# Use authentication with JSON facets
class Api::V1::UsersController < Api::V1::ApiController
def index
users = current_user.organization.users
render_facet users, :summary
end
end
Development and Testing
# Run all authentication tests
rails test test/models/user_test.rb
rails test test/controllers/auth/
rails test test/concerns/
rails test test/mailers/
# Test specific authentication flows
rails test test/controllers/auth/tokens_controller_test.rb
rails test test/controllers/auth/password_reset_integration_test.rb
# Run generator tests (if gem is in development)
cd propel_authentication
bundle exec rake test
Version History
0.2.0 (Current)
- Fixed generator extraction issues
- Enhanced JWT authentication with proper secret handling
- Complete test suite passing
- Improved "no black box" policy implementation
- Better integration with PropelRails ecosystem
Contributing
Bug reports and pull requests are welcome on GitHub at https://github.com/propel-web/propel_rails.
License
The gem is available as open source under the MIT License.