Fix bug in default argument types.
[arvados.git] / services / api / app / controllers / user_sessions_controller.rb
1 class UserSessionsController < ApplicationController
2   before_filter :require_auth_scope_all, :only => [ :destroy ]
3
4   skip_before_filter :find_object_by_uuid
5
6   respond_to :html
7
8   # omniauth callback method
9   def create
10     omniauth = env['omniauth.auth']
11     #logger.debug "+++ #{omniauth}"
12
13     identity_url_ok = (omniauth['info']['identity_url'].length > 0) rescue false
14     unless identity_url_ok
15       # Whoa. This should never happen.
16       logger.error "UserSessionsController.create: omniauth object missing/invalid"
17       logger.error "omniauth.pretty_inspect():\n\n#{omniauth.pretty_inspect()}"
18
19       return redirect_to login_failure_url
20     end
21
22     user = User.find_by_identity_url(omniauth['info']['identity_url'])
23     if not user
24       # New user registration
25       user = User.new(:email => omniauth['info']['email'],
26                       :first_name => omniauth['info']['first_name'],
27                       :last_name => omniauth['info']['last_name'],
28                       :identity_url => omniauth['info']['identity_url'],
29                       :is_active => Rails.configuration.new_users_are_active)
30     else
31       user.email = omniauth['info']['email']
32       user.first_name = omniauth['info']['first_name']
33       user.last_name = omniauth['info']['last_name']
34     end
35
36     # prevent ArvadosModel#before_create and _update from throwing
37     # "unauthorized":
38     Thread.current[:user] = user
39
40     user.save!
41
42     omniauth.delete('extra')
43
44     # Give the authenticated user a cookie for direct API access
45     session[:user_id] = user.id
46     session[:api_client_uuid] = nil
47     session[:api_client_trusted] = true # full permission to see user's secrets
48
49     @redirect_to = root_path
50     if params.has_key?(:return_to)
51       return send_api_token_to(params[:return_to], user)
52     end
53     redirect_to @redirect_to
54   end
55
56   # Omniauth failure callback
57   def failure
58     flash[:notice] = params[:message]
59   end
60
61   # logout - Clear our rack session BUT essentially redirect to the provider
62   # to clean up the Devise session from there too !
63   def logout
64     session[:user_id] = nil
65
66     flash[:notice] = 'You have logged off'
67     return_to = params[:return_to] || root_url
68     redirect_to "#{CUSTOM_PROVIDER_URL}/users/sign_out?redirect_uri=#{CGI.escape return_to}"
69   end
70
71   # login - Just bounce to /auth/joshid. The only purpose of this function is
72   # to save the return_to parameter (if it exists; see the application
73   # controller). /auth/joshid bypasses the application controller.
74   def login
75     if current_user and params[:return_to]
76       # Already logged in; just need to send a token to the requesting
77       # API client.
78       #
79       # FIXME: if current_user has never authorized this app before,
80       # ask for confirmation here!
81
82       send_api_token_to(params[:return_to], current_user)
83     elsif params[:return_to]
84       redirect_to "/auth/joshid?return_to=#{CGI.escape(params[:return_to])}"
85     else
86       redirect_to "/auth/joshid"
87     end
88   end
89
90   def send_api_token_to(callback_url, user)
91     # Give the API client a token for making API calls on behalf of
92     # the authenticated user
93
94     # Stub: automatically register all new API clients
95     api_client_url_prefix = callback_url.match(%r{^.*?://[^/]+})[0] + '/'
96     act_as_system_user do
97       @api_client = ApiClient.find_or_create_by_url_prefix api_client_url_prefix
98     end
99
100     api_client_auth = ApiClientAuthorization.
101       new(user: user,
102           api_client: @api_client,
103           created_by_ip_address: remote_ip)
104     api_client_auth.save!
105
106     if callback_url.index('?')
107       callback_url += '&'
108     else
109       callback_url += '?'
110     end
111     callback_url += 'api_token=' + api_client_auth.api_token
112     redirect_to callback_url
113   end
114 end