From 8650e494b6e9611e668add7f89f5b56672ebdcfa Mon Sep 17 00:00:00 2001
From: Khemissi Amir <amir.khemissi@insat.ucar.tn>
Date: Tue, 7 Feb 2023 16:53:40 +0100
Subject: [PATCH] Tasks: Initial `user:create` task. (#4761)

* Tasks: Initial `user:create` task.

* Tasks: Colorized the logging methods.
	+ Minor refactoring.

* Tasks: Removed unrequired features.

* Tasks: Added `admin:create` task.
---
 .rubocop.yml              |  8 +++++++
 lib/tasks/admin.rake      | 19 +++++++++++++++++
 lib/tasks/task_helpers.rb | 38 +++++++++++++++++++++++++++++++++
 lib/tasks/user.rake       | 45 +++++++++++++++++++++++++++++++++++++++
 4 files changed, 110 insertions(+)
 create mode 100644 lib/tasks/admin.rake
 create mode 100644 lib/tasks/task_helpers.rb
 create mode 100644 lib/tasks/user.rake

diff --git a/.rubocop.yml b/.rubocop.yml
index a9890ac7..670c4a18 100644
--- a/.rubocop.yml
+++ b/.rubocop.yml
@@ -81,3 +81,11 @@ Metrics/CyclomaticComplexity:
 Metrics/PerceivedComplexity:
   Max: 13
 
+Rails/Exit:
+  Exclude:
+    - 'lib/tasks/task_helpers.rb'
+
+Rails/Output:
+  Exclude:
+    - 'lib/tasks/task_helpers.rb'
+
diff --git a/lib/tasks/admin.rake b/lib/tasks/admin.rake
new file mode 100644
index 00000000..ac500f80
--- /dev/null
+++ b/lib/tasks/admin.rake
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+require_relative 'task_helpers'
+
+namespace :admin do
+  desc 'Create an administrator account'
+  task :create, %i[name email password] => :environment do |_task, args|
+    # Default values.
+    admin = {
+      name: 'Administrator',
+      email: 'admin@example.com',
+      password: 'Administrator1!'
+    }.merge(args)
+
+    Rake::Task['user:create'].invoke(admin[:name], admin[:email], admin[:password], 'Administrator')
+
+    exit 0
+  end
+end
diff --git a/lib/tasks/task_helpers.rb b/lib/tasks/task_helpers.rb
new file mode 100644
index 00000000..d243ab42
--- /dev/null
+++ b/lib/tasks/task_helpers.rb
@@ -0,0 +1,38 @@
+# frozen_string_literal: true
+
+COLORS = {
+  # https://www.ing.iac.es/~docs/external/bash/abs-guide/colorizing.html.
+  black: 30,
+  red: 31,
+  green: 32,
+  yellow: 33,
+  blue: 34,
+  magenta: 35,
+  cyan: 36,
+  white: 37
+}.freeze
+
+def err(msg)
+  color = COLORS[:red]
+
+  warn "\033[#{color}m#{msg}\033[0m"
+  exit 1
+end
+
+def warning(msg)
+  color = COLORS[:yellow]
+
+  warn "\033[#{color}m#{msg}\033[0m"
+end
+
+def info(msg)
+  color = COLORS[:cyan]
+
+  puts "\033[#{color}m#{msg}\033[0m"
+end
+
+def success(msg)
+  color = COLORS[:green]
+
+  puts "\033[#{color}m#{msg}\033[0m"
+end
diff --git a/lib/tasks/user.rake b/lib/tasks/user.rake
new file mode 100644
index 00000000..c0eefb3c
--- /dev/null
+++ b/lib/tasks/user.rake
@@ -0,0 +1,45 @@
+# frozen_string_literal: true
+
+require_relative 'task_helpers'
+
+namespace :user do
+  desc 'Create a user'
+  task :create, %i[name email password role] => :environment do |_task, args|
+    # Default values.
+    user = {
+      provider: 'greenlight',
+      verified: true,
+      status: :active,
+      language: I18n.default_locale
+    }.merge(args)
+
+    check_role!(user:)
+    user = User.new(user)
+
+    display_user_errors(user:) unless user.save
+
+    success 'User account was created successfully!'
+    info "  Name: #{user.name}"
+    info "  Email: #{user.email}"
+    info "  Password: #{user.password}"
+    info "  Role: #{user.role.name}"
+
+    exit 0
+  end
+
+  private
+
+  def check_role!(user:)
+    role_name = user[:role]
+    user[:role] = Role.find_by(name: role_name, provider: 'greenlight')
+    return if user[:role]
+
+    warning "Unable to create user: '#{user[:name]}'"
+    err "   Role '#{role_name}' does not exist, maybe you have not run the DB migrations?"
+  end
+
+  def display_user_errors(user:)
+    warning "Unable to create user: '#{user.name}'"
+    err "   Failed to pass the following validations:\n    #{user.errors.to_a}"
+  end
+end
-- 
GitLab