aboutsummaryrefslogtreecommitdiff
path: root/src/operations
diff options
context:
space:
mode:
Diffstat (limited to 'src/operations')
-rw-r--r--src/operations/.keep0
-rw-r--r--src/operations/mixins/.keep0
-rw-r--r--src/operations/mixins/password_validations.cr12
-rw-r--r--src/operations/mixins/user_from_email.cr7
-rw-r--r--src/operations/request_password_reset.cr25
-rw-r--r--src/operations/reset_password.cr11
-rw-r--r--src/operations/sign_in_user.cr40
-rw-r--r--src/operations/sign_up_user.cr14
8 files changed, 109 insertions, 0 deletions
diff --git a/src/operations/.keep b/src/operations/.keep
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/operations/.keep
diff --git a/src/operations/mixins/.keep b/src/operations/mixins/.keep
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/operations/mixins/.keep
diff --git a/src/operations/mixins/password_validations.cr b/src/operations/mixins/password_validations.cr
new file mode 100644
index 0000000..c56b975
--- /dev/null
+++ b/src/operations/mixins/password_validations.cr
@@ -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
diff --git a/src/operations/mixins/user_from_email.cr b/src/operations/mixins/user_from_email.cr
new file mode 100644
index 0000000..862fa9a
--- /dev/null
+++ b/src/operations/mixins/user_from_email.cr
@@ -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
diff --git a/src/operations/request_password_reset.cr b/src/operations/request_password_reset.cr
new file mode 100644
index 0000000..4941aa7
--- /dev/null
+++ b/src/operations/request_password_reset.cr
@@ -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
diff --git a/src/operations/reset_password.cr b/src/operations/reset_password.cr
new file mode 100644
index 0000000..3bdd3c8
--- /dev/null
+++ b/src/operations/reset_password.cr
@@ -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
diff --git a/src/operations/sign_in_user.cr b/src/operations/sign_in_user.cr
new file mode 100644
index 0000000..de80342
--- /dev/null
+++ b/src/operations/sign_in_user.cr
@@ -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
diff --git a/src/operations/sign_up_user.cr b/src/operations/sign_up_user.cr
new file mode 100644
index 0000000..8c46fad
--- /dev/null
+++ b/src/operations/sign_up_user.cr
@@ -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