1 class Arvados::V1::UsersController < ApplicationController
2 skip_before_filter :find_object_by_uuid, only:
3 [:activate, :event_stream, :current, :system]
4 skip_before_filter :render_404_if_no_object, only:
5 [:activate, :event_stream, :current, :system]
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 if params[:openid_prefix] # check if default openid_prefix needs to be overridden
94 openid_prefix = params[:openid_prefix]
96 openid_prefix = 'https://www.google.com/accounts/o8/id' # default openid prefix
98 login_perm_props = {identity_url_prefix: openid_prefix}
100 # check if only to probe the given user parameter
101 just_probe = (params[:just_probe] == 'true') ? true : false;
103 @object = model_class.new resource_attrs
105 # If user_param is passed, lookup for user. If exists, skip create and create any missing links.
106 if params[:user_param]
108 @object_found = find_user_from_user_param params[:user_param]
112 @object[:email] = params[:user_param]
113 need_to_create = true
115 @object = @object_found
117 else # need to create user for the given :user data
118 need_to_create = true
121 # if just probing, return any object found
123 @object[:email] = nil
128 # create if need be, and then create or update the links as needed
130 if @object.save # save succeeded
131 oid_login_perm = Link.where(tail_uuid: @object[:email],
132 head_kind: 'arvados#user',
133 link_class: 'permission',
136 if [] == oid_login_perm
137 # create openid login permission
138 oid_login_perm = Link.create(link_class: 'permission',
141 tail_uuid: @object[:email],
142 head_kind: 'arvados#user',
143 head_uuid: @object[:uuid],
144 properties: login_perm_props
146 logger.info { "openid login permission: " + oid_login_perm[:uuid] }
154 create_user_repo_link params[:repo_name]
155 create_vm_login_permission_link params[:vm_uuid], params[:repo_name]
156 create_user_group_link
163 # find the user from the given user parameter
164 def find_user_from_user_param(user_param)
165 found_object = User.find_by_uuid user_param
169 if !user_param.match(/\w\@\w+\.\w+/)
170 logger.warn ("Given user param is not valid email format: #{user_param}")
171 raise ArgumentError.new "User param is not of valid email format. Stop"
173 found_objects = User.where('email=?', user_param)
175 if found_objects.size > 1
176 logger.warn ("Found #{found_objects.size} users with email #{user_param}. Stop.")
177 raise ArgumentError.new "Found #{found_objects.size} users with email #{user_param}. Stop."
178 elsif found_objects.size == 1
179 found_object = found_objects.first
188 # link the repo_name passed
189 def create_user_repo_link(repo_name)
191 logger.warn ("Repository name not given for #{@object[:uuid]}. Skip creating the link")
195 # Check for an existing repository with the same name we're about to use.
196 repo = (repositories = Repository.where(name: repo_name)) != nil ? repositories.first : nil
198 logger.warn "Repository already exists with name #{repo_name}: #{repo[:uuid]}. Will link to user."
200 # Look for existing repository access (perhaps using a different repository/user name).
201 repo_perms = Link.where(tail_uuid: @object[:uuid],
202 head_kind: 'arvados#repository',
203 head_uuid: repo[:uuid],
204 link_class: 'permission',
207 logger.warn "User already has repository access " + repo_perms.collect { |p| p[:uuid] }.inspect
212 repo ||= Repository.create(name: repo_name) # create repo, if does not already exist
213 logger.info { "repo uuid: " + repo[:uuid] }
215 repo_perm = Link.create(tail_kind: 'arvados#user',
216 tail_uuid: @object[:uuid],
217 head_kind: 'arvados#repository',
218 head_uuid: repo[:uuid],
219 link_class: 'permission',
221 logger.info { "repo permission: " + repo_perm[:uuid] }
224 # create login permission for the given vm_uuid, if it does not already exist
225 def create_vm_login_permission_link(vm_uuid, repo_name)
226 # Look up the given virtual machine just to make sure it really exists.
228 vm = (vms = VirtualMachine.where(uuid: vm_uuid)) != nil ? vms.first : nil
229 #vm = VirtualMachine.where(uuid: vm_uuid)
232 logger.warn "Could not look up virtual machine with uuid #{vm_uuid.inspect}"
236 logger.info { "vm uuid: " + vm[:uuid] }
238 login_perm = Link.where(tail_uuid: @object[:uuid],
239 head_uuid: vm[:uuid],
240 head_kind: 'arvados#virtualMachine',
241 link_class: 'permission',
244 login_perm = Link.create(tail_kind: 'arvados#user',
245 tail_uuid: @object[:uuid],
246 head_kind: 'arvados#virtualMachine',
247 head_uuid: vm[:uuid],
248 link_class: 'permission',
250 properties: {username: repo_name})
251 logger.info { "login permission: " + login_perm[:uuid] }
256 # add the user to the 'All users' group
257 def create_user_group_link
258 # Look up the "All users" group (we expect uuid *-*-fffffffffffffff).
259 group = Group.where(name: 'All users').select do |g|
260 g[:uuid].match /-f+$/
264 logger.warn "Could not look up the 'All users' group with uuid '*-*-fffffffffffffff'. Skip."
267 logger.info { "\"All users\" group uuid: " + group[:uuid] }
269 group_perm = Link.where(tail_uuid: @object[:uuid],
270 head_uuid: group[:uuid],
271 head_kind: 'arvados#group',
272 link_class: 'permission',
276 group_perm = Link.create(tail_kind: 'arvados#user',
277 tail_uuid: @object[:uuid],
278 head_kind: 'arvados#group',
279 head_uuid: group[:uuid],
280 link_class: 'permission',
282 logger.info { "group permission: " + group_perm[:uuid] }