class Itch::Auth

Authentication flow handler

Attributes

password[W]
totp[W]
username[W]

Public Class Methods

new(agent, username: nil, password: nil, cookie_path: nil) click to toggle source
# File lib/itch/auth.rb, line 12
def initialize(agent, username: nil, password: nil, cookie_path: nil)
  @agent = agent
  @cookie_path = cookie_path
  @username = username
  @password = password
  @totp = -> {}
end

Public Instance Methods

logged_in?() click to toggle source
# File lib/itch/auth.rb, line 20
def logged_in?
  @agent.get(Itch::URL::DASHBOARD).uri.to_s == Itch::URL::DASHBOARD
end
login() click to toggle source
# File lib/itch/auth.rb, line 24
def login
  page = @agent.get(Itch::URL::LOGIN)
  return unless page.code == "200"
  raise AuthError, "Email and password are required for login" if @username.nil? || @password.nil?

  page = submit_login(page) if page_is_login?(page)
  submit_2fa(page) if page_is_2fa?(page)

  save_cookies

  logged_in?
end
page_is_2fa?(page) click to toggle source
# File lib/itch/auth.rb, line 41
def page_is_2fa?(page)
  page.uri.to_s.start_with?(Itch::URL::TOTP_FRAGMENT)
end
page_is_login?(page) click to toggle source
# File lib/itch/auth.rb, line 37
def page_is_login?(page)
  page.uri.to_s == Itch::URL::LOGIN
end

Protected Instance Methods

exclude_inspection() click to toggle source
Calls superclass method SimpleInspect#exclude_inspection
# File lib/itch/auth.rb, line 47
def exclude_inspection
  super + [:@password]
end
password() click to toggle source
# File lib/itch/auth.rb, line 76
def password
  return @password.call if @password.respond_to? :call

  @password
end
save_cookies() click to toggle source
# File lib/itch/auth.rb, line 51
def save_cookies
  @agent.cookie_jar.save(@cookie_path) if @cookie_path
end
submit_2fa(page) click to toggle source
# File lib/itch/auth.rb, line 55
def submit_2fa(page)
  form = page.form_with(action: page.uri.to_s)
  form.code = totp_code
  page = form.submit

  if page_is_2fa?(page)
    # 2fa failed
    errors = page.css(".form_errors li").map(&:text)
    raise AuthError, "#{errors.size} error#{errors.size == 1 ? "" : "s"} prevented 2fa validation", errors
  end

  page
end
submit_login(page) click to toggle source
# File lib/itch/auth.rb, line 88
def submit_login(page)
  form = page.form_with(action: Itch::URL::LOGIN)

  form.username = username
  form.password = password

  page = form.submit

  if page_is_login?(page)
    # Login failed
    errors = page.css(".form_errors li").map(&:text)
    raise AuthError.new("#{errors.size} error#{errors.size == 1 ? "" : "s"} prevented login", errors: errors)
  end

  page
end
totp_code() click to toggle source
# File lib/itch/auth.rb, line 69
def totp_code
  code = @totp.call
  raise AuthError, "TOTP code is required" if code.nil? || code.empty?

  code.chomp
end
username() click to toggle source
# File lib/itch/auth.rb, line 82
def username
  return @username.call if @username.respond_to? :call

  @username
end