Merge branch '2288-smoke-test'
[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, :setup]
4   skip_before_filter :render_404_if_no_object, only:
5     [:activate, :event_stream, :current, :system, :setup]
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
91   # create user object and all the needed links
92   def setup
93     @object = nil
94     if params[:uuid]
95       @object = User.find_by_uuid params[:uuid]
96       if !@object
97         return render_404_if_no_object
98       end
99       object_found = true
100     else
101       if !params[:user]
102         raise ArgumentError.new "Required uuid or user"
103       else
104         if params[:user]['uuid']
105           @object = User.find_by_uuid params[:user]['uuid']
106           if @object
107             object_found = true
108           end
109         end
110
111         if !@object
112           if !params[:user]['email']
113             raise ArgumentError.new "Require user email"
114           end
115
116           if !params[:openid_prefix]
117             raise ArgumentError.new "Required openid_prefix parameter is missing."
118           end
119
120           @object = model_class.create! resource_attrs
121         end
122       end
123     end
124
125     if object_found
126       @response = @object.setup_repo_vm_links params[:repo_name], params[:vm_uuid]
127     else
128       @response = User.setup @object, params[:openid_prefix],
129                     params[:repo_name], params[:vm_uuid]
130     end
131
132     render json: { kind: "arvados#HashList", items: @response }
133   end
134
135 end