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 @object = model_class.new resource_attrs
102 # If user_param is passed, lookup for user. If exists, skip create and only create any missing links.
103 if params[:user_param]
105 @object_found = find_user_from_input params[:user_param], params[:user_param]
108 @object = User.new # when user_param is used, it will be used as user object
109 @object[:email] = params[:user_param]
110 need_to_create = true
112 @object = @object_found
114 else # need to create user for the given user data
115 @object_found = find_user_from_input @object[:uuid], @object[:email]
117 need_to_create = true # use the user object sent in to create with the user
119 @object = @object_found
123 # create if need be, and then create or update the links as needed
126 oid_login_perm = Link.where(tail_uuid: @object[:email],
127 head_kind: 'arvados#user',
128 link_class: 'permission',
131 if [] == oid_login_perm
132 # create openid login permission
133 oid_login_perm = Link.create(link_class: 'permission',
136 tail_uuid: @object[:email],
137 head_kind: 'arvados#user',
138 head_uuid: @object[:uuid],
139 properties: login_perm_props
141 logger.info { "openid login permission: " + oid_login_perm[:uuid] }
149 create_user_repo_link params[:repo_name]
150 create_vm_login_permission_link params[:vm_uuid], params[:repo_name]
151 create_user_group_link
158 # find the user from the given user parameters
159 def find_user_from_input(user_uuid, user_email)
161 found_object = User.find_by_uuid user_uuid
170 if !user_email.match(/\w\@\w+\.\w+/)
171 logger.warn ("Given user param is not valid email format: #{user_email}")
172 raise ArgumentError.new "User param is not of valid email format. Stop"
174 found_objects = User.where('email=?', user_email)
175 if found_objects.size > 1
176 logger.warn ("Found #{found_objects.size} users with email #{user_email}. Stop.")
177 raise ArgumentError.new "Found #{found_objects.size} users with email #{user_email}. 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
230 logger.warn "Could not look up virtual machine with uuid #{vm_uuid.inspect}"
234 logger.info { "vm uuid: " + vm[:uuid] }
236 login_perm = Link.where(tail_uuid: @object[:uuid],
237 head_uuid: vm[:uuid],
238 head_kind: 'arvados#virtualMachine',
239 link_class: 'permission',
242 login_perm = Link.create(tail_kind: 'arvados#user',
243 tail_uuid: @object[:uuid],
244 head_kind: 'arvados#virtualMachine',
245 head_uuid: vm[:uuid],
246 link_class: 'permission',
248 properties: {username: repo_name})
249 logger.info { "login permission: " + login_perm[:uuid] }
254 # add the user to the 'All users' group
255 def create_user_group_link
256 # Look up the "All users" group (we expect uuid *-*-fffffffffffffff).
257 group = Group.where(name: 'All users').select do |g|
258 g[:uuid].match /-f+$/
262 logger.warn "Could not look up the 'All users' group with uuid '*-*-fffffffffffffff'. Skip."
265 logger.info { "\"All users\" group uuid: " + group[:uuid] }
267 group_perm = Link.where(tail_uuid: @object[:uuid],
268 head_uuid: group[:uuid],
269 head_kind: 'arvados#group',
270 link_class: 'permission',
274 group_perm = Link.create(tail_kind: 'arvados#user',
275 tail_uuid: @object[:uuid],
276 head_kind: 'arvados#group',
277 head_uuid: group[:uuid],
278 link_class: 'permission',
280 logger.info { "group permission: " + group_perm[:uuid] }