blob: d106868cafc3f030b0d5e1ed15913885b8f31466 [file] [log] [blame]
Copybara854996b2021-09-07 19:36:02 +00001# Copyright 2018 The Chromium Authors. All rights reserved.
2# Use of this source code is governed by a BSD-style
3# license that can be found in the LICENSE file or at
4# https://developers.google.com/open-source/licenses/bsd
5
6from __future__ import print_function
7from __future__ import division
8from __future__ import absolute_import
9
10from api import converters
11from api import monorail_servicer
12from api import converters
13from api.api_proto import users_pb2
14from api.api_proto import users_prpc_pb2
15from api.api_proto import user_objects_pb2
16from businesslogic import work_env
17from framework import authdata
18from framework import framework_views
19from framework import permissions
20
21class UsersServicer(monorail_servicer.MonorailServicer):
22 """Handle API requests related to User objects.
23
24 Each API request is implemented with a method as defined in the
25 .proto file that does any request-specific validation, uses work_env
26 to safely operate on business objects, and returns a response proto.
27 """
28
29 DESCRIPTION = users_prpc_pb2.UsersServiceDescription
30
31 @monorail_servicer.PRPCMethod
32 def GetUser(self, mc, request):
33 """Return info about the specified user."""
34 with work_env.WorkEnv(mc, self.services) as we:
35 users, linked_user_ids = we.ListReferencedUsers(
36 [request.user_ref.display_name])
37 linked_user_views = framework_views.MakeAllUserViews(
38 mc.cnxn, self.services.user, linked_user_ids)
39
40 with mc.profiler.Phase('converting to response objects'):
41 response_users = converters.ConvertUsers(users, linked_user_views)
42
43 return response_users[0]
44
45 @monorail_servicer.PRPCMethod
46 def ListReferencedUsers(self, mc, request):
47 """Return the list of existing users in a response proto."""
48 emails = request.emails
49 if request.user_refs:
50 emails = [user_ref.display_name for user_ref in request.user_refs]
51 with work_env.WorkEnv(mc, self.services) as we:
52 users, linked_user_ids = we.ListReferencedUsers(emails)
53 linked_user_views = framework_views.MakeAllUserViews(
54 mc.cnxn, self.services.user, linked_user_ids)
55
56 with mc.profiler.Phase('converting to response objects'):
57 response_users = converters.ConvertUsers(users, linked_user_views)
58 response = users_pb2.ListReferencedUsersResponse(users=response_users)
59
60 return response
61
62 @monorail_servicer.PRPCMethod
63 def GetMemberships(self, mc, request):
64 """Return the user groups for the given user visible to the requester."""
65 user_id = converters.IngestUserRef(
66 mc.cnxn, request.user_ref, self.services.user)
67
68 with work_env.WorkEnv(mc, self.services) as we:
69 group_ids = we.GetMemberships(user_id)
70
71 with mc.profiler.Phase('converting to response objects'):
72 groups_by_id = framework_views.MakeAllUserViews(
73 mc.cnxn, self.services.user, group_ids)
74 group_refs = converters.ConvertUserRefs(
75 group_ids, [], groups_by_id, True)
76
77 return users_pb2.GetMembershipsResponse(group_refs=group_refs)
78
79 @monorail_servicer.PRPCMethod
80 def GetUserStarCount(self, mc, request):
81 """Return the star count for a given user."""
82 user_id = converters.IngestUserRef(
83 mc.cnxn, request.user_ref, self.services.user)
84
85 with work_env.WorkEnv(mc, self.services) as we:
86 star_count = we.GetUserStarCount(user_id)
87
88 result = users_pb2.GetUserStarCountResponse(star_count=star_count)
89 return result
90
91 @monorail_servicer.PRPCMethod
92 def StarUser(self, mc, request):
93 """Star a given user."""
94 user_id = converters.IngestUserRef(
95 mc.cnxn, request.user_ref, self.services.user)
96
97 with work_env.WorkEnv(mc, self.services) as we:
98 we.StarUser(user_id, request.starred)
99 star_count = we.GetUserStarCount(user_id)
100
101 result = users_pb2.StarUserResponse(star_count=star_count)
102 return result
103
104 @monorail_servicer.PRPCMethod
105 def SetExpandPermsPreference(self, mc, request):
106 """Set a users preference on whether to expand perms by default."""
107 with work_env.WorkEnv(mc, self.services) as we:
108 we.UpdateUserSettings(
109 mc.auth.user_pb, keep_people_perms_open=request.expand_perms)
110
111 result = users_pb2.SetExpandPermsPreferenceResponse()
112 return result
113
114 def _SignedInOrSpecifiedUser(self, mc, request):
115 """If request specifies a user, return it. Otherwise signed-in user."""
116 user_id = mc.auth.user_id
117 if request.HasField('user_ref'):
118 user_id = converters.IngestUserRef(
119 mc.cnxn, request.user_ref, self.services.user)
120 return user_id
121
122 @monorail_servicer.PRPCMethod
123 def GetSavedQueries(self, mc, request):
124 """Get a user's saved queries."""
125 user_id = self._SignedInOrSpecifiedUser(mc, request)
126
127 # Only site admins can view other user's saved queries.
128 if user_id != mc.auth.user_id and not mc.auth.user_pb.is_site_admin:
129 raise permissions.PermissionException(
130 'You are not allowed to view this user\'s saved queries')
131
132 saved_queries = self.services.features.GetSavedQueriesByUserID(
133 mc.cnxn, user_id)
134 return users_pb2.GetSavedQueriesResponse(
135 saved_queries=converters.IngestSavedQueries(mc.cnxn,
136 self.services.project, saved_queries))
137
138 @monorail_servicer.PRPCMethod
139 def GetUserPrefs(self, mc, request):
140 """Get a user's preferences."""
141 with work_env.WorkEnv(mc, self.services) as we:
142 userprefs = we.GetUserPrefs(self._SignedInOrSpecifiedUser(mc, request))
143
144 result = users_pb2.GetUserPrefsResponse(
145 prefs=converters.ConvertPrefValues(userprefs.prefs))
146 return result
147
148 @monorail_servicer.PRPCMethod
149 def SetUserPrefs(self, mc, request):
150 """Add to or set a users preferences."""
151 with work_env.WorkEnv(mc, self.services) as we:
152 pref_values = converters.IngestPrefValues(request.prefs)
153 we.SetUserPrefs(self._SignedInOrSpecifiedUser(mc, request), pref_values)
154
155 result = users_pb2.SetUserPrefsResponse()
156 return result
157
158 @monorail_servicer.PRPCMethod
159 def InviteLinkedParent(self, mc, request):
160 """Create a linked account invite."""
161 with work_env.WorkEnv(mc, self.services) as we:
162 we.InviteLinkedParent(request.email)
163
164 result = users_pb2.InviteLinkedParentResponse()
165 return result
166
167 @monorail_servicer.PRPCMethod
168 def AcceptLinkedChild(self, mc, request):
169 """Link a child account that has invited this account as parent."""
170 child_id = self.services.user.LookupUserID(mc.cnxn, request.email)
171 with work_env.WorkEnv(mc, self.services) as we:
172 we.AcceptLinkedChild(child_id)
173
174 result = users_pb2.AcceptLinkedChildResponse()
175 return result
176
177 @monorail_servicer.PRPCMethod
178 def UnlinkAccounts(self, mc, request):
179 """Unlink a specificed parent and child account."""
180 parent_id, child_id = converters.IngestUserRefs(
181 mc.cnxn, [request.parent, request.child], self.services.user)
182 with work_env.WorkEnv(mc, self.services) as we:
183 we.UnlinkAccounts(parent_id, child_id)
184
185 result = users_pb2.UnlinkAccountsResponse()
186 return result
187
188 @monorail_servicer.PRPCMethod
189 def GetUsersProjects(self, mc, request):
190 user_ids = converters.IngestUserRefs(
191 mc.cnxn, request.user_refs, self.services.user)
192 user_auths = [
193 authdata.AuthData.FromUserID(mc.cnxn, user_id, self.services)
194 for user_id in user_ids]
195
196 result = users_pb2.GetUsersProjectsResponse()
197 with work_env.WorkEnv(mc, self.services) as we:
198 for user_ref, auth in zip(request.user_refs, user_auths):
199 starred = we.ListStarredProjects(auth.user_id)
200 owner, _archived, member, contrib = we.GetUserProjects(
201 auth.effective_ids)
202 user_projects = result.users_projects.add()
203 user_projects.user_ref.CopyFrom(user_ref)
204 user_projects.owner_of.extend(p.project_name for p in owner)
205 user_projects.member_of.extend(p.project_name for p in member)
206 user_projects.contributor_to.extend(p.project_name for p in contrib)
207 user_projects.starred_projects.extend(p.project_name for p in starred)
208
209 return result
210
211 @monorail_servicer.PRPCMethod
212 def ExpungeUser(self, mc, request):
213 with work_env.WorkEnv(mc, self.services) as we:
214 we.ExpungeUsers([request.email])
215
216 response = users_pb2.ExpungeUserResponse()
217 return response