Merge remote-tracking branch 'origin/master' into 1971-show-image-thumbnails
[arvados.git] / services / api / app / controllers / arvados / v1 / users_controller.rb
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]
6
7   def current
8     @object = current_user
9     show
10   end
11   def system
12     @object = system_user
13     show
14   end
15
16   class ChannelStreamer
17     Q_UPDATE_INTERVAL = 12
18     def initialize(opts={})
19       @opts = opts
20     end
21     def each
22       return unless @opts[:channel]
23       @redis = Redis.new(:timeout => 0)
24       @redis.subscribe(@opts[:channel]) do |event|
25         event.message do |channel, msg|
26           yield msg + "\n"
27         end
28       end
29     end
30   end
31       
32   def event_stream
33     channel = current_user.andand.uuid
34     if current_user.andand.is_admin
35       channel = params[:uuid] || channel
36     end
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)
40     else
41       render json: {
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"')
45       }
46     end
47   end
48
49   def activate
50     if current_user.andand.is_admin && params[:uuid]
51       @object = User.find params[:uuid]
52     else
53       @object = current_user
54     end
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 " +
58           "but is not invited"
59         raise ArgumentError.new "Cannot activate without being invited."
60       end
61       act_as_system_user do
62         required_uuids = Link.where(owner_uuid: system_user_uuid,
63                                     link_class: 'signature',
64                                     name: 'require',
65                                     tail_uuid: system_user_uuid,
66                                     head_kind: 'arvados#collection').
67           collect(&:head_uuid)
68         signed_uuids = Link.where(owner_uuid: system_user_uuid,
69                                   link_class: 'signature',
70                                   name: 'click',
71                                   tail_kind: 'arvados#user',
72                                   tail_uuid: @object.uuid,
73                                   head_kind: 'arvados#collection',
74                                   head_uuid: required_uuids).
75           collect(&:head_uuid)
76         todo_uuids = required_uuids - signed_uuids
77         if todo_uuids == []
78           @object.update_attributes is_active: true
79           logger.info "User #{@object.uuid} activated"
80         else
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}."
85         end
86       end
87     end
88     show
89   end
90 end