Initial commit

This commit is contained in:
Yaser
2026-08-13 19:56:46 +03:30
commit de1d57a67b
474 changed files with 43185 additions and 0 deletions

27
lib/tasks/activities.rake Normal file
View File

@@ -0,0 +1,27 @@
# frozen_string_literal: true
namespace :activities do
desc "Delete activities for specific period. From and To parameters should be on next format 'YYYY-mm-dd'"
task :delete, [:from, :to] => [:environment] do |_, args|
if args[:from].present? && args[:to].present?
if valid_date?(args[:from]) && valid_date?(args[:to])
activities = Activity.where('DATE(created_at) >= ? AND DATE(created_at) <= ?', args[:from].to_date, args[:to].to_date)
puts "Found #{activities.count} activities to delete"
activities.delete_all
end
else
puts "There is no parameters (from, to)"
end
end
def valid_date?(date)
Date.parse(date)
true
rescue ArgumentError
puts "Invalid date #{date}, should be 'YYYY-mm-dd''"
false
end
end

View File

@@ -0,0 +1,53 @@
# frozen_string_literal: true
# NOTE: only doing this in development as some production environments (Heroku)
# NOTE: are sensitive to local FS writes, and besides -- it's just not proper
# NOTE: to have a dev-mode tool do its thing in production.
if Rails.env.development? && defined?(Annotate)
task :set_annotation_options do
# You can override any of these by setting an environment variable of the
# same name.
Annotate.set_defaults \
"routes" => "false",
"position_in_routes" => "before",
"position_in_class" => "after",
"position_in_test" => "before",
"position_in_fixture" => "before",
"position_in_factory" => "before",
"position_in_serializer" => "before",
"show_foreign_keys" => "true",
"show_complete_foreign_keys" => "true",
"show_indexes" => "true",
"simple_indexes" => "false",
"model_dir" => "app/models",
"root_dir" => "",
"include_version" => "true",
"require" => "",
"exclude_tests" => "true",
"exclude_fixtures" => "true",
"exclude_factories" => "true",
"exclude_serializers" => "true",
"exclude_scaffolds" => "true",
"exclude_controllers" => "true",
"exclude_helpers" => "true",
"exclude_sti_subclasses" => "false",
"ignore_model_sub_dir" => "false",
"ignore_columns" => nil,
"ignore_routes" => nil,
"ignore_unknown_models" => "false",
"hide_limit_column_types" => "",
"hide_default_column_types" => "",
"skip_on_db_migrate" => "false",
"format_bare" => "true",
"format_rdoc" => "false",
"format_markdown" => "false",
"sort" => "false",
"force" => "false",
"trace" => "false",
"wrapper_open" => nil,
"wrapper_close" => nil,
"with_comment" => true
end
Annotate.load_tasks
end

8
lib/tasks/docker.rake Normal file
View File

@@ -0,0 +1,8 @@
namespace 'docker' do
desc "Build Application container"
task :build do
sh "docker build -t quay.io/openware/barong2:latest ."
end
end

29
lib/tasks/export.rake Normal file
View File

@@ -0,0 +1,29 @@
# frozen_string_literal: true
require 'yaml'
require 'csv'
namespace :export do
desc 'Export all users to csv file.'
task users: :environment do
count = 0
errors_count = 0
begin
CSV.open('barong_users.csv', 'w') do |csv|
csv << %w[uid email level role state]
User.find_each do |user|
csv << [user.uid, user.email, user.level, user.role, user.state]
count += 1
end
rescue StandardError => e
message = { error: e.message, email: user.email, uid: user.uid }
Rails.logger.error message
errors_count += 1
end
end
Kernel.puts "Exported #{count} users"
Kernel.puts "Errored #{errors_count}"
end
end

42
lib/tasks/generate.rake Normal file
View File

@@ -0,0 +1,42 @@
# frozen_string_literal: true
# To execute with optional user and api keys amount
# rake generate:users -- --n=1000
namespace 'generate' do
desc 'Build Application container'
task :users => :environment do
### Parse options
options = {}
o = OptionParser.new
o.banner = 'Usage: rake generate:users [-n=100]'
o.on('-n NUMBER', '--number NUMBER') { |num| options[:num] = num.to_i }
args = o.order!(ARGV) {}
o.parse!(args)
options[:num] = 10 if options[:num].nil?
result_arr = []
options[:num].times do |i|
email = Faker::Internet.email
passwd = Faker::Internet.password(min_length: 10, special_characters: true)
u = User.create(email: email, password: passwd, level: 3, state: 'active')
api_key = APIKey.create(user_id: u.id, kid: SecureRandom.hex(8), algorithm: 'HS256')
secret = SecureRandom.hex(16)
SecretStorage.store_secret(secret, api_key.kid)
result_arr.push({
'uid' => u.uid,
'email' => u.email,
'password' => passwd,
'kid' => api_key.kid,
'secret' => secret
})
end
File.write('tmp/payload.yml', result_arr.to_yaml)
end
end

71
lib/tasks/import.rake Normal file
View File

@@ -0,0 +1,71 @@
#frozen_string_literal: true
require 'csv'
namespace :import do
# Detailed instruction https://github.com/rubykube/barong/blob/master/docs/tasks/import.md
# Required fields for import users:
# - uid
# - email
#
# Usage:
# For import users: -> bundle exec rake import:users['file_name.csv']
desc 'Load users from csv file.'
task :users, [:config_load_path] => [:environment] do |_, args|
csv_table = File.read(Rails.root.join(args[:config_load_path]))
import_user_log = File.open('./log/import_users.log', 'w')
count = 0
CSV.parse(csv_table, :headers => true).map do |row|
row = row.to_h.compact.symbolize_keys!
defaults = { level: 0, role: 'member', state: 'pending', password: generate_password }
permitted_attr = %i[uid email role state]
User.new(row.slice(*permitted_attr)
.reverse_merge(defaults))
.save!
count += 1
rescue StandardError => e
message = { error: e.message, email: row[:email], uid: row[:uid] }
import_user_log.write(message.to_yaml + "\n")
end
import_user_log.close
Kernel.puts "Created #{count} members"
Kernel.puts "Errored #{CSV.parse(csv_table, headers: true).count - count}"
end
# Required fields for import referrals:
# - uid
# - referral_uid
#
# Usage:
# For import users: -> bundle exec rake import:fill_referals['file_name.csv']
desc 'users referral relation from csv file'
task :fill_referrals, [:config_load_path] => [:environment] do |_, args|
csv_table = File.read(Rails.root.join(args[:config_load_path]))
import_affiliates_log = File.open('./log/import_referrals.log', 'w')
count = 0
CSV.parse(csv_table, :headers => true).map do |row|
row = row.to_h.compact.symbolize_keys!
user = User.find_by_uid!(row[:uid])
target_user = User.find_by_uid(row[:referral_uid])
next unless target_user
user.update!(referral_id: target_user.id)
count += 1
rescue StandardError => e
message = { error: e.message, email: row[:email], uid: row[:uid], referral_uid: row[:referral_uid] }
import_affiliates_log.write(message.to_yaml + "\n")
end
import_affiliates_log.close
Kernel.puts "Created #{count} referrals"
end
def generate_password
chars = ('a'..'z').to_a
numbers = ('0'..'9').to_a
special = %w[! @ # $ % & / ( ) + ? *]
chars.sort_by { rand }.join[0..3] + chars.sort_by { rand }.join[0..3].upcase + numbers.sort_by { rand }.join[0..3] + special.sort_by { rand }.join[0..3]
end
end

23
lib/tasks/mailer.rake Normal file
View File

@@ -0,0 +1,23 @@
# frozen_string_literal: true
require 'ostruct'
namespace 'mailer' do
desc 'Generate email to the user with UID'
task :send, [:uid] => [:environment] do |_t, args|
record = OpenStruct.new
record.user = User.find_by(uid: args[:uid])
record.domain = 'barong.io'
record.token = 'TEST_TOKEN'
params = {
subject: 'Test Message',
template_name: 'email_confirmation.en.html.erb',
record: record,
changes: nil,
user: User.first
}
Postmaster.process_payload(params).deliver_now
end
end

46
lib/tasks/migrate.rake Normal file
View File

@@ -0,0 +1,46 @@
# frozen_string_literal: true
namespace 'migrate' do
desc 'Migrate api keys from vault secrets to transit'
task "26-api-keys": [:environment] do
puts 'Migrating API keys from secrets to transit keys (new in 2.6)'
APIKey.find_in_batches do |keys|
keys.each do |key|
legacy_key_path = "secret/barong/api_key/#{key.kid}"
secret = TOTPService.read_data(legacy_key_path)
next unless secret
value = secret.data[:value]
next unless value
key.secret = value
key.save!
TOTPService.delete_data(legacy_key_path)
end
end
end
desc 'Move TOTP secrets to include the vault application as prefix'
task "26-totp": [:environment] do
puts 'Moving TOTP secrets to include the vault application as prefix (new in 2.6)'
User.find_in_batches do |users|
users.each do |u|
legacy_key_path = "totp/keys/#{u.uid}"
legacy_export_path = "totp/export/#{u.uid}"
next unless TOTPService.read_data(legacy_key_path)
params = TOTPService.read_data(legacy_export_path)
unless params
raise "Failed to export key (#{legacy_export_path})\n"\
"Make sure vault is running with this image: quay.io/openware/vault:1.5.3-openware\n"\
'And make sure the token has read access to /totp/export/*'
end
key_path = TOTPService.totp_key(u.uid)
TOTPService.write_data(key_path, params.data.merge(generate: false))
TOTPService.delete_data(legacy_key_path)
end
end
end
end

View File

@@ -0,0 +1,15 @@
# frozen_string_literal: true
namespace :permissions do
desc 'Reload user permissions'
task reload: :environment do
Permission.transaction do
# Delete old permissions
Permission.delete_all
# Clean permissions cache
Rails.cache.delete('permissions')
# Load permissions
Barong::Seed.new.seed_permissions
end
end
end

24
lib/tasks/rotate.rake Normal file
View File

@@ -0,0 +1,24 @@
#frozen_string_literal: true
namespace :rotate do
desc 'Rotate profile keys'
task profiles: :environment do
Profile.find_each(batch_size: 100) do |profile|
profile.update({})
end
end
desc 'Rotate phones keys'
task phones: :environment do
Phone.find_each(batch_size: 100) do |phone|
phone.update({})
end
end
desc 'Rotate documents keys'
task documents: :environment do
Document.where.not(doc_number_encrypted: nil).find_each(batch_size: 100) do |document|
document.update({})
end
end
end

52
lib/tasks/superadmin.rake Normal file
View File

@@ -0,0 +1,52 @@
# frozen_string_literal: true
namespace :superadmin do
desc "create superadmin"
task create: :environment do
Kernel.puts "Seeding superadmin"
Barong::Seed.new().seeds["superadmin"]&.each do |seed|
Kernel.puts "---"
raise ConfigError.new("Email missing in users seed") if seed["email"].to_s.empty?
raise ConfigError.new("Level is missing for user #{seed["email"]}") unless seed["level"].is_a?(Integer)
# Skip existing users
if User.find_by(email: seed["email"], state: seed['state']).present?
Kernel.puts "User '#{seed['email']}' already exists"
next
elsif User.find_by(email: seed["email"]).present?
User.find_by(email: seed["email"]).update(state: seed['state'])
next
end
user = User.new(seed)
user.password ||= SecureRandom.base64(30)
if user.save
Kernel.puts "Created user for '#{user.email}'"
# Set correct level with labels
# levels = Level.where(id: 1..user.level)
levels = Level.where(id: 1..Level::LEVEL_ID_BOUNDS[user.level.to_s])
raise ConfigError.new("No enough levels found in database to grant the user to level #{user.level}") if levels.count < user.level
levels.find_each do |level|
user.labels.create(key: level.key, value: level.value, scope: 'private')
end
else
Kernel.puts "Can't create user '#{user.email}': #{user.errors.full_messages.join('; ')}"
end
end
end
task delete: :environment do
Kernel.puts "deleting superadmin"
Barong::Seed.new().seeds["superadmin"]&.each do |seed|
user = User.find_by(email: seed['email'])
user.update(state: 'inactive')
end
end
end