Merge branch 'master' into 3882-cancel-already-cancelled-job
[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     @object = current_user
12     show
13   end
14   def system
15     @object = system_user
16     show
17   end
18
19   def activate
20     if current_user.andand.is_admin && params[:uuid]
21       @object = User.find params[:uuid]
22     else
23       @object = current_user
24     end
25     if not @object.is_active
26       if not (current_user.is_admin or @object.is_invited)
27         logger.warn "User #{@object.uuid} called users.activate " +
28           "but is not invited"
29         raise ArgumentError.new "Cannot activate without being invited."
30       end
31       act_as_system_user do
32         required_uuids = Link.where("owner_uuid = ? and link_class = ? and name = ? and tail_uuid = ? and head_uuid like ?",
33                                     system_user_uuid,
34                                     'signature',
35                                     'require',
36                                     system_user_uuid,
37                                     Collection.uuid_like_pattern).
38           collect(&:head_uuid)
39         signed_uuids = Link.where(owner_uuid: system_user_uuid,
40                                   link_class: 'signature',
41                                   name: 'click',
42                                   tail_uuid: @object.uuid,
43                                   head_uuid: required_uuids).
44           collect(&:head_uuid)
45         todo_uuids = required_uuids - signed_uuids
46         if todo_uuids.empty?
47           @object.update_attributes is_active: true
48           logger.info "User #{@object.uuid} activated"
49         else
50           logger.warn "User #{@object.uuid} called users.activate " +
51             "before signing agreements #{todo_uuids.inspect}"
52           raise ArvadosModel::PermissionDeniedError.new \
53           "Cannot activate without user agreements #{todo_uuids.inspect}."
54         end
55       end
56     end
57     show
58   end
59
60   # create user object and all the needed links
61   def setup
62     @object = nil
63     if params[:uuid]
64       @object = User.find_by_uuid params[:uuid]
65       if !@object
66         return render_404_if_no_object
67       end
68       object_found = true
69     else
70       if !params[:user]
71         raise ArgumentError.new "Required uuid or user"
72       else
73         if params[:user]['uuid']
74           @object = User.find_by_uuid params[:user]['uuid']
75           if @object
76             object_found = true
77           end
78         end
79
80         if !@object
81           if !params[:user]['email']
82             raise ArgumentError.new "Require user email"
83           end
84
85           if !params[:openid_prefix]
86             raise ArgumentError.new "Required openid_prefix parameter is missing."
87           end
88
89           @object = model_class.create! resource_attrs
90         end
91       end
92     end
93
94     if object_found
95       @response = @object.setup_repo_vm_links params[:repo_name],
96                     params[:vm_uuid], params[:openid_prefix]
97     else
98       @response = User.setup @object, params[:openid_prefix],
99                     params[:repo_name], params[:vm_uuid]
100     end
101
102     # setup succeeded. send email to user
103     if params[:send_notification_email] == true || params[:send_notification_email] == 'true'
104       UserNotifier.account_is_setup(@object).deliver
105     end
106
107     render 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
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