Class: RubyNative::OAuthMiddleware

Inherits:
Object
  • Object
show all
Defined in:
lib/ruby_native/oauth_middleware.rb

Constant Summary collapse

"_ruby_native_oauth"

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(app) ⇒ OAuthMiddleware

Returns a new instance of OAuthMiddleware.



5
6
7
# File 'lib/ruby_native/oauth_middleware.rb', line 5

def initialize(app)
  @app = app
end

Class Method Details

.build_token(cookies:, redirect_url:) ⇒ Object



56
57
58
59
60
61
62
# File 'lib/ruby_native/oauth_middleware.rb', line 56

def self.build_token(cookies:, redirect_url:)
  encryptor.encrypt_and_sign(
    {cookies: cookies, redirect_url: redirect_url},
    expires_in: 5.minutes,
    purpose: "ruby_native_oauth"
  )
end

.encryptorObject



48
49
50
51
52
53
54
# File 'lib/ruby_native/oauth_middleware.rb', line 48

def self.encryptor
  @encryptor ||= begin
    key = ActiveSupport::KeyGenerator.new(Rails.application.secret_key_base)
      .generate_key("ruby_native_oauth", ActiveSupport::MessageEncryptor.key_len)
    ActiveSupport::MessageEncryptor.new(key)
  end
end

.read_token(token) ⇒ Object



64
65
66
67
68
69
# File 'lib/ruby_native/oauth_middleware.rb', line 64

def self.read_token(token)
  data = encryptor.decrypt_and_verify(token, purpose: "ruby_native_oauth")
  data&.symbolize_keys
rescue ActiveSupport::MessageEncryptor::InvalidMessage
  nil
end

Instance Method Details

#call(env) ⇒ Object



9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# File 'lib/ruby_native/oauth_middleware.rb', line 9

def call(env)
  request = ActionDispatch::Request.new(env)
  on_oauth_path = oauth_path?(request)
  started_native_oauth = on_oauth_path && request.params["ruby_native"] == "1"
  callback_scheme = request.params["callback_scheme"] if started_native_oauth

  status, headers, body = @app.call(env)

  if on_oauth_path && redirect?(status) && (started_native_oauth || read_cookie(request))
    relax_cookie_samesite!(headers)
  end

  if started_native_oauth && callback_scheme.present? && redirect?(status)
    Rails.logger.debug { "[RubyNative] OAuth started for #{request.path}, setting tracking cookie" }
    set_cookie(headers, callback_scheme)
  end

  stored_scheme = read_cookie(request)

  if stored_scheme && redirect?(status)
    location = headers["location"] || headers["Location"]

    if auth_failure?(location)
      Rails.logger.info { "[RubyNative] OAuth failed, redirecting to native app" }
      delete_cookie(headers)
      return redirect_to_native(stored_scheme, error: true)
    end

    if internal_redirect?(request, location)
      token = build_token(headers, location)
      Rails.logger.info { "[RubyNative] OAuth succeeded, redirecting to native app" }
      delete_cookie(headers)
      return redirect_to_native(stored_scheme, token: token)
    end
  end

  [status, headers, body]
end