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}."
89 @object = User.find @object[:uuid]
93 # create user object and all the needed links
95 if params[:openid_prefix] # check if default openid_prefix needs to be overridden
96 openid_prefix = params[:openid_prefix]
98 openid_prefix = 'https://www.google.com/accounts/o8/id' # default openid prefix
100 login_perm_props = {identity_url_prefix: openid_prefix}
102 # check if only to probe the given user parameter
103 just_probe = (params[:just_probe] == 'true') ? true : false;
105 puts "\n*******************************\nparams = #{params}"
106 puts "\n*******************************\nlogin_perm_props = #{login_perm_props.inspect}"
107 puts "\n*******************************\njust_probe = #{just_probe}"
109 @object = model_class.new resource_attrs
111 # If user_param is passed, lookup for user. If exists, skip create and create any missing links.
112 if params[:user_param]
114 @object_found = find_user_from_user_param params[:user_param]
118 @object[:email] = params[:user_param]
119 need_to_create = true
121 @object = @object_found
123 else # need to create user for the given :user data
124 need_to_create = true
127 # if just probing, return any object found
132 # create if need be, and then create or update the links as needed
135 # create openid login permission
136 oid_login_perm = Link.create(link_class: 'permission',
139 tail_uuid: @object[:email],
140 head_kind: 'arvados#user',
141 head_uuid: @object[:uuid],
142 properties: login_perm_props
144 logger.info { "openid login permission: " + oid_login_perm[:uuid] }
151 link_repo params[:repo_name]
152 vm_login_permission params[:vm_uuid]
160 # find the user from the given user parameter
161 def find_user_from_user_param(user_param)
162 found_object = User.find_by_uuid user_param
163 puts "found by uuid = #{found_object.inspect}"
165 puts "didnt find by uuid. trying email"
167 if !user_param.match(/\w\@\w+\.\w+/)
168 logger.warn ("Given user param is not valid email format: #{user_param}")
169 raise ArgumentError.new "User param is not of valid email format. Stop"
171 found_objects = User.where('email=?', user_param)
173 if found_objects.size > 1
174 logger.warn ("Found #{found_objects.size} users with email #{user_param}. Stop.")
175 raise ArgumentError.new "Found #{found_objects.size} users with email #{user_param}. Stop."
176 elsif found_objects.size == 1
177 found_object = found_objects.first
186 # link the repo_name passed
187 def link_repo(repo_name)
189 logger.warn ("Repository name not given for #{@object[:uuid]}. Skip creating the link")
193 # Look for existing repository access (perhaps using a different repository/user name).
194 repo_perms = Link.where(tail_uuid: @object[:uuid],
195 head_kind: 'arvados#repository',
196 link_class: 'permission',
200 logger.warn "User already has repository access " + repo_perms.collect { |p| p[:uuid] }.inspect
204 # Check for an existing repository with the same name we're about to use.
205 repo = Repository.where(name: repo_name).first
207 logger.warn "Repository already exists with name #{repo_name}: #{repo[:uuid]}"
211 repo ||= Repository.create(name: repo_name)
212 logger.info { "repo uuid: " + repo[:uuid] }
214 repo_perm = Link.create(tail_kind: 'arvados#user',
215 tail_uuid: @object[:uuid],
216 head_kind: 'arvados#repository',
217 head_uuid: repo[:uuid],
218 link_class: 'permission',
220 logger.info { "repo permission: " + repo_perm[:uuid] }
223 # create login permission for the given vm_uuid, if it does not already exist
224 def vm_login_permission(vm_uuid)
225 # Look up the given virtual machine just to make sure it really exists.
227 vm = VirtualMachine.get(uuid: vm_uuid)
231 # check vm is not already linked first
234 logger.info { "vm uuid: " + vm[:uuid] }
236 login_perm = Link.create(tail_kind: 'arvados#user',
237 tail_uuid: @object[:uuid],
238 head_kind: 'arvados#virtualMachine',
239 head_uuid: vm[:uuid],
240 link_class: 'permission',
242 properties: {username: repo_name})
243 logger.info { "login permission: " + login_perm[:uuid] }
245 logger.warn "Could not look up virtual machine with uuid #{vm_uuid.inspect}. Skip."
249 # add the user to the 'All users' group
251 # Look up the "All users" group (we expect uuid *-*-fffffffffffffff).
252 group = Group.where(name: 'All users').select do |g|
253 g[:uuid].match /-f+$/
257 logger.warn "Could not look up the 'All users' group with uuid '*-*-fffffffffffffff'. Skip."
259 logger.info { "\"All users\" group uuid: " + group[:uuid] }
261 # link the user to 'All users' group, if not already linked
265 group_perm = Link.create(tail_kind: 'arvados#user',
266 tail_uuid: @object[:uuid],
267 head_kind: 'arvados#group',
268 head_uuid: group[:uuid],
269 link_class: 'permission',
271 logger.info { "group permission: " + group_perm[:uuid] }