Class: Mytotp::Commands::Generate

Inherits:
Dry::CLI::Command
  • Object
show all
Defined in:
lib/mytotp/commands/generate.rb

Overview

Class command for generate a totp token.

Instance Method Summary collapse

Instance Method Details

#call(service: nil, username: nil, **options) ⇒ Object

call the command function

Parameters:

  • service (String) (defaults to: nil)

    Service’s name to generate the totp code.

  • username (String) (defaults to: nil)

    Service’s username to generate the totp code.



16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# File 'lib/mytotp/commands/generate.rb', line 16

def call(service: nil, username: nil, **options)
  # find services
  services = Mytotp::Models::Service.where(Sequel.ilike(:service, "%#{service}%"))
                                    .where(Sequel.ilike(:username, "%#{username}%"))
  # select one service
  service =
    if services.count == 1
      found_one_message(services)
      services.first
    elsif services.count > 1
      select_one(services)
    else
      select_one(Mytotp::Models::Service.all)
    end
  # generate the complete message with the code
  generate_code(service, options.fetch(:mode))
end

#clear_last_lineObject

clear last line in the console



82
83
84
85
86
87
# File 'lib/mytotp/commands/generate.rb', line 82

def clear_last_line
  # Clear the line
  print(CLI::UI::ANSI.previous_line + CLI::UI::ANSI.clear_to_end_of_line)
  # Force StdoutRouter to prefix
  print("#{CLI::UI::ANSI.previous_line} \n")
end

#copy_to_clipboard(code) ⇒ Boolean

Copy code to clipboar

Parameters:

  • code (String)

    Code to be copy on the clipboard.

Returns:

  • (Boolean)

    True or false depending if it was copy to clipboard or not.



121
122
123
124
# File 'lib/mytotp/commands/generate.rb', line 121

def copy_to_clipboard(code)
  Clipboard.copy(code)
  Clipboard.paste == code
end

#found_one_message(services) ⇒ Object

Print message when is found one

Parameters:



37
38
39
40
# File 'lib/mytotp/commands/generate.rb', line 37

def found_one_message(services)
  puts CLI::UI.fmt "{{green:Service:}} #{services.first.service.capitalize}"
  puts CLI::UI.fmt "{{green:Username:}} #{services.first.username.capitalize}"
end

#generate_code(service, mode) ⇒ Object

Generate the complete message with the code

Parameters:

  • service (Mytotp::Models::Service)

    Selected service for generate the totp code

  • mode (String)

    Mode for generate the code, it can be ‘continuos’ or by default ‘once’



58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# File 'lib/mytotp/commands/generate.rb', line 58

def generate_code(service, mode)
  totp = ROTP::TOTP.new(service.key, interval: service.period, digits: service.digits)
  if mode == 'continuos'
    # infinit loop
    loop do
      actual_code = totp.now
      message_code(actual_code)
      loop do
        message_valid_for(service, totp)
        sleep 1
        clear_last_line
        break unless totp.verify(actual_code)
      end
      clear_last_line
    end
  else
    # print once
    message_code(totp.now)
    message_valid_for(service, totp)
  end
end

#message_code(totp) ⇒ Object

Print the code

Parameters:

  • totp (String)

    totp code generate for print.



109
110
111
112
113
114
115
# File 'lib/mytotp/commands/generate.rb', line 109

def message_code(totp)
  if copy_to_clipboard(totp)
    puts CLI::UI.fmt "{{green:Current TOTP:}} #{totp} - {{green:Copy!}}"
  else
    puts CLI::UI.fmt "{{green:Current TOTP:}} #{totp} - {{red:It can't be copy.Do it manually.}}"
  end
end

#message_valid_for(service, totp) ⇒ Object

Print valid for

Parameters:

  • service (Mytotp::Models::Service)

    Service to validate.

  • totp (ROTP::TOTP)

    totp object generated with the service token.



102
103
104
# File 'lib/mytotp/commands/generate.rb', line 102

def message_valid_for(service, totp)
  puts CLI::UI.fmt "{{green:Valid for:}} #{valid_for(service, totp)} seconds"
end

#select_one(services) ⇒ Mytotp::Models::Service

Ask which service when we have more than one found.

Parameters:

Returns:



46
47
48
49
50
51
52
# File 'lib/mytotp/commands/generate.rb', line 46

def select_one(services)
  CLI::UI::Prompt.ask('Which service?') do |handler|
    services.each do |s|
      handler.option("#{s.service} : #{s.username}") { |_selection| s }
    end
  end
end

#valid_for(service, totp) ⇒ Integer

Count seconds

Parameters:

  • service (Mytotp::Models::Service)

    Service to validate.

  • totp (ROTP::TOTP)

    totp object generated with the service token.

Returns:

  • (Integer)

    seconds



94
95
96
# File 'lib/mytotp/commands/generate.rb', line 94

def valid_for(service, totp)
  (service.period - (Time.now - Time.at(totp.verify(totp.now)))).round
end