Initial commit
This commit is contained in:
104
app/services/totp_service_action.rb
Normal file
104
app/services/totp_service_action.rb
Normal file
@@ -0,0 +1,104 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class TOTPServiceAction
|
||||
Error = Class.new(StandardError)
|
||||
|
||||
ISSUER_NAME = 'Barong'
|
||||
attr_reader :action
|
||||
|
||||
def initialize(action)
|
||||
raise 'Please determine action for totp code' if action.blank?
|
||||
|
||||
@action = action
|
||||
end
|
||||
|
||||
def server_available?
|
||||
read_data('sys/health').present?
|
||||
rescue StandardError
|
||||
false
|
||||
end
|
||||
|
||||
def otp_secret(otp)
|
||||
CGI.parse(URI.parse(otp.data[:url]).query)['secret'][0]
|
||||
end
|
||||
|
||||
def safe_create(uid, email)
|
||||
return if exist?(uid)
|
||||
|
||||
create(uid, email)
|
||||
end
|
||||
|
||||
def create(uid, email, period: '120')
|
||||
write_data(totp_key(uid),
|
||||
generate: true,
|
||||
issuer: ::Barong::App.config.app_name,
|
||||
period: period, account_name: email, qr_size: 300)
|
||||
end
|
||||
|
||||
def exist?(uid)
|
||||
read_data(totp_key(uid)).present?
|
||||
end
|
||||
|
||||
def validate?(uid, code)
|
||||
return false unless exist?(uid)
|
||||
|
||||
result = write_data(totp_code_key(uid), code: code)
|
||||
return false unless result
|
||||
|
||||
result.data[:valid]
|
||||
end
|
||||
|
||||
def safe_validate?(uid, code)
|
||||
return false unless exist?(uid)
|
||||
|
||||
code == read_code(uid)
|
||||
end
|
||||
|
||||
|
||||
def delete(uid)
|
||||
delete_data(totp_key(uid))
|
||||
end
|
||||
|
||||
def with_human_error
|
||||
raise ArgumentError, 'Block is required' unless block_given?
|
||||
|
||||
yield
|
||||
rescue Vault::VaultError => e
|
||||
Rails.logger.error { e }
|
||||
|
||||
false
|
||||
end
|
||||
|
||||
def totp_key(uid)
|
||||
"totp/keys/#{Vault.application}_#{@action}_#{uid}"
|
||||
end
|
||||
|
||||
def totp_code_key(uid)
|
||||
"totp/code/#{Vault.application}_#{@action}_#{uid}"
|
||||
end
|
||||
|
||||
def read_data(key)
|
||||
with_human_error do
|
||||
vault.read(key)
|
||||
end
|
||||
end
|
||||
|
||||
def read_code(uid)
|
||||
read_data(totp_code_key(uid)).data[:code]
|
||||
end
|
||||
|
||||
def write_data(key, params)
|
||||
with_human_error { vault.write(key, params) }
|
||||
end
|
||||
|
||||
def delete_data(key)
|
||||
with_human_error do
|
||||
vault.delete(key)
|
||||
end
|
||||
end
|
||||
|
||||
def vault
|
||||
Vault.logical
|
||||
end
|
||||
|
||||
end
|
||||
Reference in New Issue
Block a user