blob: 2dac146de65bc9a1caef9f6430a03e91eb208a18 [file] [log] [blame]
Copybara854996b2021-09-07 19:36:02 +00001# Copyright 2016 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
6"""A page for site admins to create a new user group."""
7from __future__ import print_function
8from __future__ import division
9from __future__ import absolute_import
10
11import logging
12import re
13
14from framework import exceptions
15from framework import framework_helpers
16from framework import permissions
17from framework import servlet
18from proto import usergroup_pb2
19from sitewide import group_helpers
20
21
22class GroupCreate(servlet.Servlet):
23 """Shows a page with a simple form to create a user group."""
24
25 _PAGE_TEMPLATE = 'sitewide/group-create-page.ezt'
26
27 def AssertBasePermission(self, mr):
28 """Assert that the user has the permissions needed to view this page."""
29 super(GroupCreate, self).AssertBasePermission(mr)
30
31 if not permissions.CanCreateGroup(mr.perms):
32 raise permissions.PermissionException(
33 'User is not allowed to create a user group')
34
35 def GatherPageData(self, _mr):
36 """Build up a dictionary of data values to use when rendering the page."""
37 visibility_levels = group_helpers.BuildUserGroupVisibilityOptions()
38 initial_visibility = group_helpers.GroupVisibilityView(
39 usergroup_pb2.MemberVisibility.ANYONE)
40 group_types = group_helpers.BuildUserGroupTypeOptions()
41
42 return {
43 'groupadmin': '',
44 'group_types': group_types,
45 'import_group': '',
46 'initial_friendprojects': '',
47 'initial_group_type': '',
48 'initial_name': '',
49 'initial_visibility': initial_visibility,
50 'visibility_levels': visibility_levels,
51 }
52
53 def ProcessFormData(self, mr, post_data):
54 """Process the posted form."""
55 # 1. Gather data from the request.
56 group_name = post_data.get('groupname')
57 try:
58 existing_group_id = self.services.user.LookupUserID(mr.cnxn, group_name)
59 existing_settings = self.services.usergroup.GetGroupSettings(
60 mr.cnxn, existing_group_id)
61 if existing_settings:
62 mr.errors.groupname = 'That user group already exists'
63 except exceptions.NoSuchUserException:
64 pass
65
66 if post_data.get('import_group'):
67 vis = usergroup_pb2.MemberVisibility.OWNERS
68 ext_group_type = post_data.get('group_type')
69 friend_projects = ''
70 if not ext_group_type:
71 mr.errors.groupimport = 'Please provide external group type'
72 else:
73 ext_group_type = str(
74 usergroup_pb2.GroupType(int(ext_group_type))).lower()
75
76 if (ext_group_type == 'computed' and
77 not group_name.startswith('everyone@')):
78 mr.errors.groupimport = 'Computed groups must be named everyone@'
79
80 else:
81 vis = usergroup_pb2.MemberVisibility(int(post_data['visibility']))
82 ext_group_type = None
83 friend_projects = post_data.get('friendprojects', '')
84 who_can_view_members = str(vis).lower()
85
86 if not mr.errors.AnyErrors():
87 project_ids, error = self.services.usergroup.ValidateFriendProjects(
88 mr.cnxn, self.services, friend_projects)
89 if error:
90 mr.errors.friendprojects = error
91
92 # 2. Call services layer to save changes.
93 if not mr.errors.AnyErrors():
94 group_id = self.services.usergroup.CreateGroup(
95 mr.cnxn, self.services, group_name, who_can_view_members,
96 ext_group_type, project_ids)
97
98 # 3. Determine the next page in the UI flow.
99 if mr.errors.AnyErrors():
100 self.PleaseCorrect(mr, initial_name=group_name)
101 else:
102 # Go to the new user group's detail page.
103 return framework_helpers.FormatAbsoluteURL(
104 mr, '/g/%s/' % group_id, include_project=False)