8784: Fix test for latest firefox.
[arvados.git] / services / api / app / controllers / arvados / v1 / users_controller.rb
1 class Arvados::V1::UsersController < ApplicationController
2   accept_attribute_as_json :prefs, Hash
3
4   skip_before_filter :find_object_by_uuid, only:
5     [:activate, :current, :system, :setup]
6   skip_before_filter :render_404_if_no_object, only:
7     [:activate, :current, :system, :setup]
8   before_filter :admin_required, only: [:setup, :unsetup]
9
10   def current
11     if current_user
12       @object = current_user
13       show
14     else
15       send_error("Not logged in", status: 401)
16     end
17   end
18
19   def system
20     @object = system_user
21     show
22   end
23
24   def activate
25     if current_user.andand.is_admin && params[:uuid]
26       @object = User.find params[:uuid]
27     else
28       @object = current_user
29     end
30     if not @object.is_active
31       if not (current_user.is_admin or @object.is_invited)
32         logger.warn "User #{@object.uuid} called users.activate " +
33           "but is not invited"
34         raise ArgumentError.new "Cannot activate without being invited."
35       end
36       act_as_system_user do
37         required_uuids = Link.where("owner_uuid = ? and link_class = ? and name = ? and tail_uuid = ? and head_uuid like ?",
38                                     system_user_uuid,
39                                     'signature',
40                                     'require',
41                                     system_user_uuid,
42                                     Collection.uuid_like_pattern).
43           collect(&:head_uuid)
44         signed_uuids = Link.where(owner_uuid: system_user_uuid,
45                                   link_class: 'signature',
46                                   name: 'click',
47                                   tail_uuid: @object.uuid,
48                                   head_uuid: required_uuids).
49           collect(&:head_uuid)
50         todo_uuids = required_uuids - signed_uuids
51         if todo_uuids.empty?
52           @object.update_attributes is_active: true
53           logger.info "User #{@object.uuid} activated"
54         else
55           logger.warn "User #{@object.uuid} called users.activate " +
56             "before signing agreements #{todo_uuids.inspect}"
57           raise ArvadosModel::PermissionDeniedError.new \
58           "Cannot activate without user agreements #{todo_uuids.inspect}."
59         end
60       end
61     end
62     show
63   end
64
65   # create user object and all the needed links
66   def setup
67     if params[:uuid]
68       @object = User.find_by_uuid(params[:uuid])
69       if !@object
70         return render_404_if_no_object
71       end
72     elsif !params[:user]
73       raise ArgumentError.new "Required uuid or user"
74     elsif !params[:user]['email']
75       raise ArgumentError.new "Require user email"
76     elsif !params[:openid_prefix]
77       raise ArgumentError.new "Required openid_prefix parameter is missing."
78     else
79       @object = model_class.create! resource_attrs
80     end
81
82     # It's not always possible for the client to know the user's
83     # username when submitting this request: the username might have
84     # been assigned automatically in create!() above. If client
85     # provided a plain repository name, prefix it with the username
86     # now that we know what it is.
87     if params[:repo_name].nil?
88       full_repo_name = nil
89     elsif @object.username.nil?
90       raise ArgumentError.
91         new("cannot setup a repository because user has no username")
92     elsif params[:repo_name].index("/")
93       full_repo_name = params[:repo_name]
94     else
95       full_repo_name = "#{@object.username}/#{params[:repo_name]}"
96     end
97
98     @response = @object.setup(repo_name: full_repo_name,
99                               vm_uuid: params[:vm_uuid],
100                               openid_prefix: params[:openid_prefix])
101
102     # setup succeeded. send email to user
103     if params[:send_notification_email]
104       UserNotifier.account_is_setup(@object).deliver_now
105     end
106
107     send_json kind: "arvados#HashList", items: @response.as_api_response(nil)
108   end
109
110   # delete user agreements, vm, repository, login links; set state to inactive
111   def unsetup
112     reload_object_before_update
113     @object.unsetup
114     show
115   end
116
117   protected
118
119   def self._setup_requires_parameters
120     {
121       user: {
122         type: 'object', required: false
123       },
124       openid_prefix: {
125         type: 'string', required: false
126       },
127       repo_name: {
128         type: 'string', required: false
129       },
130       vm_uuid: {
131         type: 'string', required: false
132       },
133       send_notification_email: {
134         type: 'boolean', required: false, default: false
135       },
136     }
137   end
138
139   def apply_filters(model_class=nil)
140     return super if @read_users.any?(&:is_admin)
141     if params[:uuid] != current_user.andand.uuid
142       # Non-admin index/show returns very basic information about readable users.
143       safe_attrs = ["uuid", "is_active", "email", "first_name", "last_name"]
144       if @select
145         @select = @select & safe_attrs
146       else
147         @select = safe_attrs
148       end
149       @filters += [['is_active', '=', true]]
150     end
151     super
152   end
153 end