# 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