Merge branch '16104-select-uuid'
[arvados.git] / apps / workbench / app / models / user.rb
1 # Copyright (C) The Arvados Authors. All rights reserved.
2 #
3 # SPDX-License-Identifier: AGPL-3.0
4
5 class User < ArvadosBase
6   def initialize(*args)
7     super(*args)
8     @attribute_sortkey['first_name'] = '050'
9     @attribute_sortkey['last_name'] = '051'
10   end
11
12   def self.current
13     res = arvados_api_client.api self, '/current', nil, {}, false
14     arvados_api_client.unpack_api_response(res)
15   end
16
17   def self.merge new_user_token, direction
18     # Merge user accounts.
19     #
20     # If the direction is "in", the current user is merged into the
21     # user represented by new_user_token
22     #
23     # If the direction is "out", the user represented by new_user_token
24     # is merged into the current user.
25
26     if direction == "in"
27       user_a = new_user_token
28       user_b = Thread.current[:arvados_api_token]
29       new_group_name = "Migrated from #{Thread.current[:user].email} (#{Thread.current[:user].uuid})"
30     elsif direction == "out"
31       user_a = Thread.current[:arvados_api_token]
32       user_b = new_user_token
33       res = arvados_api_client.api self, '/current', nil, {:arvados_api_token => user_b}, false
34       user_b_info = arvados_api_client.unpack_api_response(res)
35       new_group_name = "Migrated from #{user_b_info.email} (#{user_b_info.uuid})"
36     else
37       raise "Invalid merge direction, expected 'in' or 'out'"
38     end
39
40     # Create a project owned by user_a to accept everything owned by user_b
41     res = arvados_api_client.api Group, nil, {:group => {
42                                                 :name => new_group_name,
43                                                 :group_class => "project"},
44                                               :ensure_unique_name => true},
45                                  {:arvados_api_token => user_a}, false
46     target = arvados_api_client.unpack_api_response(res)
47
48     # The merge API merges the "current" user (user_b) into the user
49     # represented by "new_user_token" (user_a).
50     # After merging, the user_b redirects to user_a.
51     res = arvados_api_client.api self, '/merge', {:new_user_token => user_a,
52                                                   :new_owner_uuid => target[:uuid],
53                                                   :redirect_to_new_user => true},
54                                  {:arvados_api_token => user_b}, false
55     arvados_api_client.unpack_api_response(res)
56   end
57
58   def self.system
59     @@arvados_system_user ||= begin
60                                 res = arvados_api_client.api self, '/system'
61                                 arvados_api_client.unpack_api_response(res)
62                               end
63   end
64
65   def full_name
66     (self.first_name || "") + " " + (self.last_name || "")
67   end
68
69   def activate
70     self.private_reload(arvados_api_client.api(self.class,
71                                                "/#{self.uuid}/activate",
72                                                {}))
73   end
74
75   def contents params={}
76     Group.contents params.merge(uuid: self.uuid)
77   end
78
79   def attributes_for_display
80     super.reject { |k,v| %w(owner_uuid default_owner_uuid identity_url prefs).index k }
81   end
82
83   def attribute_editable?(attr, ever=nil)
84     (ever or not (self.uuid.andand.match(/000000000000000$/) and
85                   self.is_admin)) and super
86   end
87
88   def friendly_link_name lookup=nil
89     [self.first_name, self.last_name].compact.join ' '
90   end
91
92   def unsetup
93     self.private_reload(arvados_api_client.api(self.class,
94                                                "/#{self.uuid}/unsetup",
95                                                {}))
96   end
97
98   def self.setup params
99     arvados_api_client.api(self, "/setup", params)
100   end
101
102   def update_profile params
103     self.private_reload(arvados_api_client.api(self.class,
104                                                "/#{self.uuid}/profile",
105                                                params))
106   end
107
108   def deletable?
109     false
110   end
111
112   def self.creatable?
113     current_user and current_user.is_admin
114   end
115 end