Class: FaradayMiddleware::Reddit::Authentication

Inherits:
Faraday::Middleware
  • Object
show all
Includes:
ModhashHelpers
Defined in:
lib/faraday_middleware/reddit/request/authentication.rb

Overview

Request middleware that automatically handles user login.

Requires that either a ‘user` and `password` are provided or a pre-generated `cookie`. Performs an additional login request when no valid login cookie is available.

Constant Summary collapse

AUTH_DOMAIN =
'https://ssl.reddit.com'.freeze
AUTH_PATH =
"/api/login".freeze
AUTH_URL =
"#{AUTH_DOMAIN}#{AUTH_PATH}"

Instance Method Summary collapse

Methods included from ModhashHelpers

#extract_modhash, included

Constructor Details

#initialize(app, options) ⇒ Authentication

Returns a new instance of Authentication.



19
20
21
22
23
24
25
26
27
28
29
30
31
# File 'lib/faraday_middleware/reddit/request/authentication.rb', line 19

def initialize(app, options)
  super(app)
  @options      = options
  @user         = @options[:user]
  @passwd       = @options[:password]
  @rem          = @options[:remember]
  @access_token = @options[:access_token]
  @cookie       = @options[:cookie]

  unless (@options[:user] && @options[:password]) || @options[:cookie] || @options[:access_token]
    fail ArgumentError, 'Either `user` and `password`, `cookie`, or `access_token` need to be provided as options to the :reddit_authentication middleware'
  end
end

Instance Method Details

#apply_access_token(env) ⇒ Object



46
47
48
49
50
51
# File 'lib/faraday_middleware/reddit/request/authentication.rb', line 46

def apply_access_token(env)
  env.url.scheme = 'https'
  env.url.port = 443
  env.url.host = 'oauth.reddit.com'
  env[:request_headers]['Authorization'] = "bearer #{@access_token}"
end


53
54
55
56
# File 'lib/faraday_middleware/reddit/request/authentication.rb', line 53

def apply_cookie(env)
  upstream_cookies = env[:request_headers]['Cookie']
  env[:request_headers]['Cookie'] = upstream_cookies ? "#{upstream_cookies}; #{@cookie}" : @cookie
end

#authenticate(env) ⇒ Object



58
59
60
61
62
# File 'lib/faraday_middleware/reddit/request/authentication.rb', line 58

def authenticate(env)
  response = connection(env).post AUTH_PATH, user: @user, passwd: @passwd, rem: @rem, api_type: 'json'
  env[:modhash] = extract_modhash(response.env)
  @cookie = response.headers['set-cookie']
end

#call(env) ⇒ Object



33
34
35
36
37
38
39
40
41
42
43
44
# File 'lib/faraday_middleware/reddit/request/authentication.rb', line 33

def call(env)
  if @access_token
    apply_access_token(env)
  elsif @cookie
    apply_cookie(env)
  else
    authenticate(env)
    apply_cookie(env)
  end

  @app.call(env)
end

#connection(env) ⇒ Object



64
65
66
67
68
69
70
71
# File 'lib/faraday_middleware/reddit/request/authentication.rb', line 64

def connection(env)
  Faraday.new(url: AUTH_DOMAIN, headers: env['request_headers']) do |faraday|
    faraday.request  :url_encoded
    faraday.request  :retry, max: 5, interval: 2, exceptions: FaradayMiddleware::Reddit::RETRIABLE_ERRORS
    faraday.response :reddit_raise_error
    faraday.adapter  Faraday.default_adapter
  end
end