Skip to content

Instantly share code, notes, and snippets.

@paulcsmith
Last active March 8, 2018 21:22
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save paulcsmith/2c1d797759bfb436ac5aa7587bdf0835 to your computer and use it in GitHub Desktop.
Save paulcsmith/2c1d797759bfb436ac5aa7587bdf0835 to your computer and use it in GitHub Desktop.
For sign up and sign in (authentication)
class Somethings::Index < BrowserAction
before require_sign_in
action { "do stuff" }
# You can extract all this to a module since you'll likely use it in multiple places
# Probably in src/pipes/authentication.cr or something
private def require_sign_in
if signed_in?
continue
else
flash.info = "Must be signed in"
redirect to: SignIns::New
end
end
private def signed_in?
!!current_user
end
private def current_user : User?
user_id = session["user_id"]?
if user_id
UserQuery.find(user_id)
end
end
end
require "crypto/bcrypt/password"
# VirtualForms are used when not saving to the database
class SignInForm < LuckyRecord::VirtualForm
allow_virtual email : String
allow_virtual password : String
def submit
validate_required email, password
yield self, signed_in_user
end
private def signed_in_user : User?
user = UserQuery.new.email(email.value).first?
if user && password_matches?(user)
user
end
end
private def password_matches?(user : User) : Bool
# This may not be right. Check out Bcrypt docs: https://crystal-lang.org/api/0.24.1/Crypto/Bcrypt/Password.html
Crypto::Bcrypt::Password.new(user.encrypted_password) == password.value
end
end
class SignIns::Create < BrowserAction
action do
SignInForm.submit(params) do |form, user|
if user
session[:user_id] = user.id.to_s
redirect to: SomeAction
else
render SignIns::New, form: form
end
end
end
end
require "crypto/bcrypt/password"
# Requires a table with
# * email : String
# * encrypted_password : String
class SignUpForm < User::BaseForm
allow email
allow_virtual password : String
allow_virtual password_confirmation : String
def prepare
validation_confirmation_of password, with: password_confirmation
encrypt_password
end
private def encrypt_password
# If the password is entered, encrypt it
password.value.try do |value|
encrypted_password.value = Bcrypt::Password.create(value, cost: 10).to_s
end
end
end
class SignUps::Create < BrowserAction
action do
SignUpForm.create(params) do |form, user|
if user
# sign in the user
session[:user_id] = user.id.to_s
redirect to: SomeAction
else
render SignUps::NewPage, form: form
end
end
end
end
# This is pretty much the same for both sign in and sign up
class SignUps::New < BrowserAction
action do
render form: SignUpForm.new
end
end
class SignUps::NewPage < MainLayout
needs form : SignUpForm
def content
form_for SignUps::Create do
label_for form.email
text_input form.email, autofocus: "true"
errors_for form.email
label_for form.password
password_input form.password
errors_for form.password
label_for form.password_confirmation
password_input form.password_confirmation
errors_for form.password_confirmation
submit "Sign up!"
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment