Class: DeviseTokenAuth::OmniauthCallbacksController

Inherits:
ApplicationController show all
Defined in:
app/controllers/devise_token_auth/omniauth_callbacks_controller.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#auth_paramsObject (readonly)

Returns the value of attribute auth_params.



4
5
6
# File 'app/controllers/devise_token_auth/omniauth_callbacks_controller.rb', line 4

def auth_params
  @auth_params
end

Instance Method Details

#assert_is_devise_resource!Object

ensure that this controller responds to :devise_controller? conditionals. this is used primarily for access to the parameter sanitizers.



241
242
243
# File 'app/controllers/devise_token_auth/omniauth_callbacks_controller.rb', line 241

def assert_is_devise_resource!
  true
end

#assign_provider_attrs(user, auth_hash) ⇒ Object

break out provider attribute assignment for easy method extension



149
150
151
152
153
154
155
156
# File 'app/controllers/devise_token_auth/omniauth_callbacks_controller.rb', line 149

def assign_provider_attrs(user, auth_hash)
  user.assign_attributes({
    nickname: auth_hash['info']['nickname'],
    name:     auth_hash['info']['name'],
    image:    auth_hash['info']['image'],
    email:    auth_hash['info']['email']
  })
end

#auth_hashObject

this sesison value is set by the redirect_callbacks method. its purpose is to persist the omniauth auth hash value thru a redirect. the value must be destroyed immediatly after it is accessed by omniauth_success



234
235
236
237
# File 'app/controllers/devise_token_auth/omniauth_callbacks_controller.rb', line 234

def auth_hash
  @_auth_hash ||= session.delete('dta.omniauth.auth')
  @_auth_hash
end

#auth_origin_urlObject



221
222
223
# File 'app/controllers/devise_token_auth/omniauth_callbacks_controller.rb', line 221

def auth_origin_url
  omniauth_params['auth_origin_url'] || omniauth_params['origin']
end

#create_auth_paramsObject



63
64
65
66
67
68
69
70
71
72
73
# File 'app/controllers/devise_token_auth/omniauth_callbacks_controller.rb', line 63

def create_auth_params
  @auth_params = {
    auth_token:     @token,
    client_id: @client_id,
    uid:       @resource.uid,
    expiry:    @expiry,
    config:    @config
  }
  @auth_params.merge!(oauth_registration: true) if @oauth_registration
  @auth_params
end

#create_token_infoObject



55
56
57
58
59
60
61
# File 'app/controllers/devise_token_auth/omniauth_callbacks_controller.rb', line 55

def create_token_info
  # create token info
  @client_id = SecureRandom.urlsafe_base64(nil, false)
  @token     = SecureRandom.urlsafe_base64(nil, false)
  @expiry    = (Time.now + DeviseTokenAuth.token_lifespan).to_i
  @config    = omniauth_params['config_name']
end

#devise_mappingObject

necessary for access to devise_parameter_sanitizers



246
247
248
249
250
251
252
# File 'app/controllers/devise_token_auth/omniauth_callbacks_controller.rb', line 246

def devise_mapping
  if omniauth_params
    Devise.mappings[omniauth_params['resource_class'].underscore.to_sym]
  else
    request.env['devise.mapping']
  end
end

#fallback_render(text) ⇒ Object



116
117
118
119
120
121
122
123
124
125
# File 'app/controllers/devise_token_auth/omniauth_callbacks_controller.rb', line 116

def fallback_render(text)
    render inline: %Q|

        <html>
                <head></head>
                <body>
                        #{text}
                </body>
        </html>| 
end

#get_resource_from_auth_hashObject



25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'app/controllers/devise_token_auth/omniauth_callbacks_controller.rb', line 25

def get_resource_from_auth_hash
  # find or create user by provider and provider uid
  @resource = resource_class.where({
    uid:      auth_hash['uid'],
    provider: auth_hash['provider']
  }).first_or_initialize

  if @resource.new_record?
    @oauth_registration = true
    set_random_password
  end

  # sync user info with provider, update/generate auth token
  assign_provider_attrs(@resource, auth_hash)

  # assign any additional (whitelisted) attributes
  extra_params = whitelisted_params
  @resource.assign_attributes(extra_params) if extra_params

  @resource
end

#omniauth_failureObject



159
160
161
162
# File 'app/controllers/devise_token_auth/omniauth_callbacks_controller.rb', line 159

def omniauth_failure
  @error = params[:message]
  render_data_or_redirect('authFailure', {error: @error})
end

#omniauth_paramsObject

this will be determined differently depending on the action that calls it. redirect_callbacks is called upon returning from successful omniauth authentication, and the target params live in an omniauth-specific request.env variable. this variable is then persisted thru the redirect using our own dta.omniauth.params session var. the omniauth_success method will access that session var and then destroy it immediately after use. In the failure case, finally, the omniauth params are added as query params in our monkey patch to OmniAuth in engine.rb



200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
# File 'app/controllers/devise_token_auth/omniauth_callbacks_controller.rb', line 200

def omniauth_params
  if !defined?(@_omniauth_params)
    if request.env['omniauth.params'] && request.env['omniauth.params'].any?
      @_omniauth_params = request.env['omniauth.params']
    elsif session['dta.omniauth.params'] && session['dta.omniauth.params'].any?
      @_omniauth_params ||= session.delete('dta.omniauth.params')
      @_omniauth_params
    elsif params['omniauth_window_type']
      @_omniauth_params = params.slice('omniauth_window_type', 'auth_origin_url', 'resource_class', 'origin')
    else
      @_omniauth_params = {}
    end
  end
  @_omniauth_params
  
end

#omniauth_successObject



127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
# File 'app/controllers/devise_token_auth/omniauth_callbacks_controller.rb', line 127

def omniauth_success
  get_resource_from_auth_hash
  create_token_info
  set_token_on_resource
  create_auth_params

  if resource_class.devise_modules.include?(:confirmable)
    # don't send confirmation email!!!
    @resource.skip_confirmation!
  end

  (:user, @resource, store: false, bypass: false)

  @resource.save!

  yield if block_given?

  render_data_or_redirect('deliverCredentials', @resource.as_json.merge(@auth_params.as_json))
end

#omniauth_window_typeObject

in the success case, omniauth_window_type is in the omniauth_params. in the failure case, it is in a query param. See monkey patch above



227
228
229
# File 'app/controllers/devise_token_auth/omniauth_callbacks_controller.rb', line 227

def omniauth_window_type
  omniauth_params['omniauth_window_type']
end

#redirect_callbacksObject

intermediary route for successful omniauth authentication. omniauth does not support multiple models, so we must resort to this terrible hack.



10
11
12
13
14
15
16
17
18
19
20
21
22
23
# File 'app/controllers/devise_token_auth/omniauth_callbacks_controller.rb', line 10

def redirect_callbacks

  # derive target redirect route from 'resource_class' param, which was set
  # before authentication.
  devise_mapping = request.env['omniauth.params']['resource_class'].underscore.to_sym
  redirect_route = "/#{Devise.mappings[devise_mapping].as_json["path"]}/#{params[:provider]}/callback"

  # preserve omniauth info for success route. ignore 'extra' in twitter
  # auth response to avoid CookieOverflow.
  session['dta.omniauth.auth'] = request.env['omniauth.auth'].except('extra')
  session['dta.omniauth.params'] = request.env['omniauth.params']

  redirect_to redirect_route
end

#render_data(message, data) ⇒ Object



82
83
84
85
86
87
# File 'app/controllers/devise_token_auth/omniauth_callbacks_controller.rb', line 82

def render_data(message, data)
  @data = data.merge({
    message: message
  })
  render :layout => nil, :template => "devise_token_auth/omniauth_external_window"
end

#render_data_or_redirect(message, data) ⇒ Object



89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
# File 'app/controllers/devise_token_auth/omniauth_callbacks_controller.rb', line 89

def render_data_or_redirect(message, data)

  # We handle inAppBrowser and newWindow the same, but it is nice
  # to support values in case people need custom implementations for each case
  # (For example, nbrustein does not allow new users to be created if logging in with
  # an inAppBrowser)
  #
  # See app/views/devise_token_auth/omniauth_external_window.html.erb to understand
  # why we can handle these both the same.  The view is setup to handle both cases
  # at the same time.
  if ['inAppBrowser', 'newWindow'].include?(omniauth_window_type)
    render_data(message, data)

  elsif auth_origin_url # default to same-window implementation, which forwards back to auth_origin_url

    # build and redirect to destination url
    redirect_to DeviseTokenAuth::Url.generate(auth_origin_url, data)
  else
    
    # there SHOULD always be an auth_origin_url, but if someone does something silly
    # like coming straight to this url or refreshing the page at the wrong time, there may not be one.
    # In that case, just render in plain text the error message if there is one or otherwise 
    # a generic message.
    fallback_render data[:error] || 'An error occurred'
  end
end

#resource_class(mapping = nil) ⇒ Object



178
179
180
181
182
183
184
185
186
# File 'app/controllers/devise_token_auth/omniauth_callbacks_controller.rb', line 178

def resource_class(mapping = nil)
  if omniauth_params['resource_class']
    omniauth_params['resource_class'].constantize
  elsif params['resource_class']
    params['resource_class'].constantize
  else
    raise "No resource_class found"
  end
end

#resource_nameObject



188
189
190
# File 'app/controllers/devise_token_auth/omniauth_callbacks_controller.rb', line 188

def resource_name
  resource_class
end

#set_random_passwordObject



47
48
49
50
51
52
53
# File 'app/controllers/devise_token_auth/omniauth_callbacks_controller.rb', line 47

def set_random_password
  # set crazy password for new oauth users. this is only used to prevent
    # access via email sign-in.
    p = SecureRandom.urlsafe_base64(nil, false)
    @resource.password = p
    @resource.password_confirmation = p
end

#set_token_on_resourceObject



75
76
77
78
79
80
# File 'app/controllers/devise_token_auth/omniauth_callbacks_controller.rb', line 75

def set_token_on_resource
  @resource.tokens[@client_id] = {
    token: BCrypt::Password.create(@token),
    expiry: @expiry
  }
end

#whitelisted_paramsObject

derive allowed params from the standard devise parameter sanitizer



166
167
168
169
170
171
172
173
174
175
176
# File 'app/controllers/devise_token_auth/omniauth_callbacks_controller.rb', line 166

def whitelisted_params
  whitelist = devise_parameter_sanitizer.for(:sign_up)

  whitelist.inject({}){|coll, key|
    param = omniauth_params[key.to_s]
    if param
      coll[key] = param
    end
    coll
  }
end