Skip to content

Commit

Permalink
feat: base_authentication_src_template specs
Browse files Browse the repository at this point in the history
  • Loading branch information
mdwagner committed Sep 22, 2023
1 parent 01e84bf commit 7f07b2c
Show file tree
Hide file tree
Showing 16 changed files with 166 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
require "./server"

Authentic.configure do |settings|
settings.secret_key = Lucky::Server.settings.secret_key_base

unless LuckyEnv.production?
# This value can be between 4 and 31
fastest_encryption_possible = 4
settings.encryption_cost = fastest_encryption_possible
end
end
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
class CreateUsers::V00000000000001 < Avram::Migrator::Migration::V1
def migrate
enable_extension "citext"

create table_for(User) do
primary_key id : Int64
add_timestamps
add email : String, unique: true, case_sensitive: false
add encrypted_password : String
end
end

def rollback
drop table_for(User)
disable_extension "citext"
end
end
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
class UserFactory < Avram::Factory
def initialize
email "#{sequence("test-email")}@example.com"
encrypted_password Authentic.generate_encrypted_password("password")
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
class User < BaseModel
include Carbon::Emailable
include Authentic::PasswordAuthenticatable

table do
column email : String
column encrypted_password : String
end

def emailable : Carbon::Address
Carbon::Address.new(email)
end
end
Empty file.
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
module PasswordValidations
macro included
before_save run_password_validations
end

private def run_password_validations
validate_required password, password_confirmation
validate_confirmation_of password, with: password_confirmation
# 72 is a limitation of BCrypt
validate_size_of password, min: 6, max: 72
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
module UserFromEmail
private def user_from_email : User?
email.value.try do |value|
UserQuery.new.email(value).first?
end
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
class RequestPasswordReset < Avram::Operation
# You can modify this in src/operations/mixins/user_from_email.cr
include UserFromEmail

attribute email : String

# Run validations and yield the operation and the user if valid
def run
user = user_from_email
validate(user)

if valid?
user
else
nil
end
end

def validate(user : User?)
validate_required email
if user.nil?
email.add_error "is not in our system"
end
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
class ResetPassword < User::SaveOperation
# Change password validations in src/operations/mixins/password_validations.cr
include PasswordValidations

attribute password : String
attribute password_confirmation : String

before_save do
Authentic.copy_and_encrypt password, to: encrypted_password
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
class SignInUser < Avram::Operation
param_key :user
# You can modify this in src/operations/mixins/user_from_email.cr
include UserFromEmail

attribute email : String
attribute password : String

# Run validations and yields the operation and the user if valid
def run
user = user_from_email
validate_credentials(user)

if valid?
user
else
nil
end
end

# `validate_credentials` determines if a user can sign in.
#
# If desired, you can add additional checks in this method, e.g.
#
# if user.locked?
# email.add_error "is locked out"
# end
private def validate_credentials(user)
if user
unless Authentic.correct_password?(user, password.value.to_s)
password.add_error "is wrong"
end
else
# Usually ok to say that an email is not in the system:
# https://kev.inburke.com/kevin/invalid-username-or-password-useless/
# https://github.com/luckyframework/lucky_cli/issues/192
email.add_error "is not in our system"
end
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
class SignUpUser < User::SaveOperation
param_key :user
# Change password validations in src/operations/mixins/password_validations.cr
include PasswordValidations

permit_columns email
attribute password : String
attribute password_confirmation : String

before_save do
validate_uniqueness_of email
Authentic.copy_and_encrypt(password, to: encrypted_password) if password.valid?
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
class UserQuery < User::BaseQuery
end
8 changes: 8 additions & 0 deletions spec/generators_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -162,4 +162,12 @@ describe "Generators" do
end
end
end

describe BaseAuthenticationSrcTemplate do
it "generates base authentication src template" do
generate_snapshot("base_authentication_src_template") do
BaseAuthenticationSrcTemplate.new
end
end
end
end

0 comments on commit 7f07b2c

Please sign in to comment.