Line data Source code
1 : // Copyright (C) 2014 The Android Open Source Project
2 : //
3 : // Licensed under the Apache License, Version 2.0 (the "License");
4 : // you may not use this file except in compliance with the License.
5 : // You may obtain a copy of the License at
6 : //
7 : // http://www.apache.org/licenses/LICENSE-2.0
8 : //
9 : // Unless required by applicable law or agreed to in writing, software
10 : // distributed under the License is distributed on an "AS IS" BASIS,
11 : // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 : // See the License for the specific language governing permissions and
13 : // limitations under the License.
14 :
15 : package com.google.gerrit.server.schema;
16 :
17 : import static com.google.common.base.Preconditions.checkArgument;
18 : import static com.google.gerrit.server.group.SystemGroupBackend.REGISTERED_USERS;
19 : import static com.google.gerrit.server.schema.AclUtil.grant;
20 : import static com.google.gerrit.server.schema.AllProjectsInput.getDefaultCodeReviewLabel;
21 :
22 : import com.google.gerrit.common.Nullable;
23 : import com.google.gerrit.common.UsedAt;
24 : import com.google.gerrit.common.Version;
25 : import com.google.gerrit.entities.GroupReference;
26 : import com.google.gerrit.entities.LabelId;
27 : import com.google.gerrit.entities.LabelType;
28 : import com.google.gerrit.entities.Permission;
29 : import com.google.gerrit.entities.RefNames;
30 : import com.google.gerrit.server.GerritPersonIdent;
31 : import com.google.gerrit.server.config.AllUsersName;
32 : import com.google.gerrit.server.extensions.events.GitReferenceUpdated;
33 : import com.google.gerrit.server.git.GitRepositoryManager;
34 : import com.google.gerrit.server.git.meta.MetaDataUpdate;
35 : import com.google.gerrit.server.group.SystemGroupBackend;
36 : import com.google.gerrit.server.project.ProjectConfig;
37 : import com.google.gerrit.server.project.RefPattern;
38 : import com.google.inject.Inject;
39 : import java.io.IOException;
40 : import org.eclipse.jgit.errors.ConfigInvalidException;
41 : import org.eclipse.jgit.errors.RepositoryNotFoundException;
42 : import org.eclipse.jgit.lib.Constants;
43 : import org.eclipse.jgit.lib.PersonIdent;
44 : import org.eclipse.jgit.lib.RefUpdate;
45 : import org.eclipse.jgit.lib.Repository;
46 :
47 : /** Creates the {@code All-Users} repository. */
48 : public class AllUsersCreator {
49 : private final GitRepositoryManager mgr;
50 : private final AllUsersName allUsersName;
51 : private final PersonIdent serverUser;
52 : private final ProjectConfig.Factory projectConfigFactory;
53 : private final GroupReference registered;
54 :
55 : @Nullable private GroupReference admin;
56 : private LabelType codeReviewLabel;
57 :
58 : @Inject
59 : AllUsersCreator(
60 : GitRepositoryManager mgr,
61 : AllUsersName allUsersName,
62 : SystemGroupBackend systemGroupBackend,
63 : @GerritPersonIdent PersonIdent serverUser,
64 151 : ProjectConfig.Factory projectConfigFactory) {
65 151 : this.mgr = mgr;
66 151 : this.allUsersName = allUsersName;
67 151 : this.serverUser = serverUser;
68 151 : this.registered = systemGroupBackend.getGroup(REGISTERED_USERS);
69 151 : this.projectConfigFactory = projectConfigFactory;
70 151 : this.codeReviewLabel = getDefaultCodeReviewLabel();
71 151 : }
72 :
73 : /**
74 : * If setAdministrators() is called, grant the given administrator group permissions on the
75 : * default user.
76 : */
77 : public AllUsersCreator setAdministrators(GroupReference admin) {
78 151 : this.admin = admin;
79 151 : return this;
80 : }
81 :
82 : /** If called, the provided "Code-Review" label will be used rather than the default. */
83 : @UsedAt(UsedAt.Project.GOOGLE)
84 : public AllUsersCreator setCodeReviewLabel(LabelType labelType) {
85 0 : checkArgument(
86 0 : labelType.getName().equals(LabelId.CODE_REVIEW),
87 : "label should have 'Code-Review' as its name");
88 0 : this.codeReviewLabel = labelType;
89 0 : return this;
90 : }
91 :
92 : public void create() throws IOException, ConfigInvalidException {
93 0 : try (Repository git = mgr.openRepository(allUsersName)) {
94 0 : initAllUsers(git);
95 151 : } catch (RepositoryNotFoundException notFound) {
96 151 : try (Repository git = mgr.createRepository(allUsersName)) {
97 151 : initAllUsers(git);
98 151 : RefUpdate u = git.updateRef(Constants.HEAD);
99 151 : u.link(RefNames.REFS_CONFIG);
100 0 : } catch (RepositoryNotFoundException err) {
101 0 : String name = allUsersName.get();
102 0 : throw new IOException("Cannot create repository " + name, err);
103 151 : }
104 0 : }
105 151 : }
106 :
107 : private void initAllUsers(Repository git) throws IOException, ConfigInvalidException {
108 151 : try (MetaDataUpdate md = new MetaDataUpdate(GitReferenceUpdated.DISABLED, allUsersName, git)) {
109 151 : md.getCommitBuilder().setAuthor(serverUser);
110 151 : md.getCommitBuilder().setCommitter(serverUser);
111 151 : md.setMessage("Initialized Gerrit Code Review " + Version.getVersion());
112 :
113 151 : ProjectConfig config = projectConfigFactory.read(md);
114 151 : config.updateProject(p -> p.setDescription("Individual user settings and preferences."));
115 :
116 151 : config.upsertAccessSection(
117 : RefNames.REFS_USERS + "${" + RefPattern.USERID_SHARDED + "}",
118 : users -> {
119 151 : grant(config, users, Permission.READ, false, true, registered);
120 151 : grant(config, users, Permission.PUSH, false, true, registered);
121 151 : grant(config, users, Permission.SUBMIT, false, true, registered);
122 151 : grant(config, users, codeReviewLabel, -2, 2, true, registered);
123 151 : });
124 :
125 : // Initialize "Code-Review" label.
126 151 : config.upsertLabelType(codeReviewLabel);
127 :
128 151 : if (admin != null) {
129 151 : config.upsertAccessSection(
130 : RefNames.REFS_USERS_DEFAULT,
131 : defaults -> {
132 151 : defaults.upsertPermission(Permission.READ).setExclusiveGroup(true);
133 151 : grant(config, defaults, Permission.READ, admin);
134 151 : defaults.upsertPermission(Permission.PUSH).setExclusiveGroup(true);
135 151 : grant(config, defaults, Permission.PUSH, admin);
136 151 : defaults.upsertPermission(Permission.CREATE).setExclusiveGroup(true);
137 151 : grant(config, defaults, Permission.CREATE, admin);
138 151 : });
139 : }
140 :
141 : // Grant read permissions on the group branches to all users.
142 : // This allows group owners to see the group refs. VisibleRefFilter ensures that read
143 : // permissions for non-group-owners are ignored.
144 151 : config.upsertAccessSection(
145 : RefNames.REFS_GROUPS + "*",
146 : groups -> {
147 151 : grant(config, groups, Permission.READ, false, true, registered);
148 151 : });
149 :
150 151 : config.commit(md);
151 : }
152 151 : }
153 : }
|