1 class Arvados::V1::UsersController < ApplicationController
2 skip_before_filter :find_object_by_uuid, only:
3 [:activate, :event_stream, :current, :system, :setup]
4 skip_before_filter :render_404_if_no_object, only:
5 [:activate, :event_stream, :current, :system, :setup]
17 Q_UPDATE_INTERVAL = 12
18 def initialize(opts={})
22 return unless @opts[:channel]
23 @redis = Redis.new(:timeout => 0)
24 @redis.subscribe(@opts[:channel]) do |event|
25 event.message do |channel, msg|
33 channel = current_user.andand.uuid
34 if current_user.andand.is_admin
35 channel = params[:uuid] || channel
37 if client_accepts_plain_text_stream
38 self.response.headers['Last-Modified'] = Time.now.ctime.to_s
39 self.response_body = ChannelStreamer.new(channel: channel)
42 href: url_for(uuid: channel),
43 comment: ('To retrieve the event stream as plain text, ' +
44 'use a request header like "Accept: text/plain"')
50 if current_user.andand.is_admin && params[:uuid]
51 @object = User.find params[:uuid]
53 @object = current_user
55 if not @object.is_active
56 if not (current_user.is_admin or @object.is_invited)
57 logger.warn "User #{@object.uuid} called users.activate " +
59 raise ArgumentError.new "Cannot activate without being invited."
62 required_uuids = Link.where(owner_uuid: system_user_uuid,
63 link_class: 'signature',
65 tail_uuid: system_user_uuid,
66 head_kind: 'arvados#collection').
68 signed_uuids = Link.where(owner_uuid: system_user_uuid,
69 link_class: 'signature',
71 tail_kind: 'arvados#user',
72 tail_uuid: @object.uuid,
73 head_kind: 'arvados#collection',
74 head_uuid: required_uuids).
76 todo_uuids = required_uuids - signed_uuids
78 @object.update_attributes is_active: true
79 logger.info "User #{@object.uuid} activated"
81 logger.warn "User #{@object.uuid} called users.activate " +
82 "before signing agreements #{todo_uuids.inspect}"
83 raise ArvadosModel::PermissionDeniedError.new \
84 "Cannot activate without user agreements #{todo_uuids.inspect}."
91 # create user object and all the needed links
93 # check if default openid_prefix needs to be overridden
94 if params[:openid_prefix]
95 openid_prefix = params[:openid_prefix]
97 openid_prefix = Rails.configuration.openid_prefix
99 login_perm_props = {identity_url_prefix: openid_prefix}
101 @object = model_class.new resource_attrs
103 # Lookup for user. If exists, only create any missing links
104 @object_found = find_user_from_input
108 raise "No email found in the input. Aborting user creation."
112 oid_login_perm = Link.where(tail_uuid: @object[:email],
113 head_kind: 'arvados#user',
114 link_class: 'permission',
117 if [] == oid_login_perm
118 # create openid login permission
119 oid_login_perm = Link.create(link_class: 'permission',
122 tail_uuid: @object[:email],
123 head_kind: 'arvados#user',
124 head_uuid: @object[:uuid],
125 properties: login_perm_props
127 logger.info { "openid login permission: " + oid_login_perm[:uuid] }
133 @object = @object_found
137 create_user_repo_link params[:repo_name]
138 create_vm_login_permission_link params[:vm_uuid], params[:repo_name]
139 create_user_group_link
146 # find the user from the given user parameters
147 def find_user_from_input
149 found_object = User.find_by_uuid @object[:uuid]
157 found_objects = User.where('email=?', @object[:email])
158 found_object = found_objects.first
164 # link the repo_name passed
165 def create_user_repo_link(repo_name)
167 logger.warn ("Repository name not given for #{@object[:uuid]}.")
171 # Check for an existing repository with the same name we're about to use.
172 repo = (repos = Repository.where(name: repo_name)) != nil ? repos.first : nil
174 logger.warn "Repository exists for #{repo_name}: #{repo[:uuid]}."
176 # Look for existing repository access for this repo
177 repo_perms = Link.where(tail_uuid: @object[:uuid],
178 head_kind: 'arvados#repository',
179 head_uuid: repo[:uuid],
180 link_class: 'permission',
183 logger.warn "User already has repository access " +
184 repo_perms.collect { |p| p[:uuid] }.inspect
189 # create repo, if does not already exist
190 repo ||= Repository.create(name: repo_name)
191 logger.info { "repo uuid: " + repo[:uuid] }
193 repo_perm = Link.create(tail_kind: 'arvados#user',
194 tail_uuid: @object[:uuid],
195 head_kind: 'arvados#repository',
196 head_uuid: repo[:uuid],
197 link_class: 'permission',
199 logger.info { "repo permission: " + repo_perm[:uuid] }
202 # create login permission for the given vm_uuid, if it does not already exist
203 def create_vm_login_permission_link(vm_uuid, repo_name)
204 # Look up the given virtual machine just to make sure it really exists.
206 vm = (vms = VirtualMachine.where(uuid: vm_uuid)) != nil ? vms.first : nil
208 logger.warn "Could not find virtual machine for #{vm_uuid.inspect}"
212 logger.info { "vm uuid: " + vm[:uuid] }
214 login_perm = Link.where(tail_uuid: @object[:uuid],
215 head_uuid: vm[:uuid],
216 head_kind: 'arvados#virtualMachine',
217 link_class: 'permission',
220 login_perm = Link.create(tail_kind: 'arvados#user',
221 tail_uuid: @object[:uuid],
222 head_kind: 'arvados#virtualMachine',
223 head_uuid: vm[:uuid],
224 link_class: 'permission',
226 properties: {username: repo_name})
227 logger.info { "login permission: " + login_perm[:uuid] }
232 # add the user to the 'All users' group
233 def create_user_group_link
234 # Look up the "All users" group (we expect uuid *-*-fffffffffffffff).
235 group = Group.where(name: 'All users').select do |g|
236 g[:uuid].match /-f+$/
240 logger.warn "No 'All users' group with uuid '*-*-fffffffffffffff'."
243 logger.info { "\"All users\" group uuid: " + group[:uuid] }
245 group_perm = Link.where(tail_uuid: @object[:uuid],
246 head_uuid: group[:uuid],
247 head_kind: 'arvados#group',
248 link_class: 'permission',
252 group_perm = Link.create(tail_kind: 'arvados#user',
253 tail_uuid: @object[:uuid],
254 head_kind: 'arvados#group',
255 head_uuid: group[:uuid],
256 link_class: 'permission',
258 logger.info { "group permission: " + group_perm[:uuid] }