]> source.dussan.org Git - sonarqube.git/blob
ed2cf0c2ac1e6181dfaf79cdb2588392da742d5a
[sonarqube.git] /
1 /*
2  * SonarQube
3  * Copyright (C) 2009-2022 SonarSource SA
4  * mailto:info AT sonarsource DOT com
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 3 of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
19  */
20 package org.sonar.server.tester;
21
22 import com.google.common.collect.HashMultimap;
23 import com.google.common.collect.ImmutableSet;
24 import java.util.Arrays;
25 import java.util.HashMap;
26 import java.util.HashSet;
27 import java.util.Map;
28 import java.util.Optional;
29 import java.util.Set;
30 import java.util.stream.Collectors;
31 import org.sonar.api.web.UserRole;
32 import org.sonar.db.component.ComponentDto;
33 import org.sonar.db.permission.GlobalPermission;
34 import org.sonar.db.portfolio.PortfolioDto;
35 import org.sonar.db.project.ProjectDto;
36 import org.sonar.server.user.AbstractUserSession;
37
38 import static com.google.common.base.Preconditions.checkArgument;
39
40 public abstract class AbstractMockUserSession<T extends AbstractMockUserSession> extends AbstractUserSession {
41   private static final Set<String> PUBLIC_PERMISSIONS = ImmutableSet.of(UserRole.USER, UserRole.CODEVIEWER); // FIXME to check with Simon
42
43   private final Class<T> clazz;
44   private final HashMultimap<String, String> projectUuidByPermission = HashMultimap.create();
45   private final Set<GlobalPermission> permissions = new HashSet<>();
46   private final Map<String, String> projectUuidByComponentUuid = new HashMap<>();
47   private final Map<String, Set<String>> applicationProjects = new HashMap<>();
48   private final Map<String, Set<String>> portfolioProjects = new HashMap<>();
49   private final Set<String> projectPermissions = new HashSet<>();
50   private boolean systemAdministrator = false;
51   private boolean resetPassword = false;
52
53   protected AbstractMockUserSession(Class<T> clazz) {
54     this.clazz = clazz;
55   }
56
57   public T addPermission(GlobalPermission permission) {
58     permissions.add(permission);
59     return clazz.cast(this);
60   }
61
62   @Override
63   protected boolean hasPermissionImpl(GlobalPermission permission) {
64     return permissions.contains(permission);
65   }
66
67   /**
68    * Use this method to register public root component and non root components the UserSession must be aware of.
69    * (ie. this method can be used to emulate the content of the DB)
70    */
71   public T registerComponents(ComponentDto... components) {
72     Arrays.stream(components)
73       .forEach(component -> {
74         if (component.projectUuid().equals(component.uuid()) && !component.isPrivate()) {
75           this.projectUuidByPermission.put(UserRole.USER, component.uuid());
76           this.projectUuidByPermission.put(UserRole.CODEVIEWER, component.uuid());
77           this.projectPermissions.add(UserRole.USER);
78           this.projectPermissions.add(UserRole.CODEVIEWER);
79         }
80         this.projectUuidByComponentUuid.put(component.uuid(), component.projectUuid());
81       });
82     return clazz.cast(this);
83   }
84
85   public T registerProjects(ProjectDto... projects) {
86     Arrays.stream(projects)
87       .forEach(project -> {
88         if (!project.isPrivate()) {
89           this.projectUuidByPermission.put(UserRole.USER, project.getUuid());
90           this.projectUuidByPermission.put(UserRole.CODEVIEWER, project.getUuid());
91           this.projectPermissions.add(UserRole.USER);
92           this.projectPermissions.add(UserRole.CODEVIEWER);
93         }
94         this.projectUuidByComponentUuid.put(project.getUuid(), project.getUuid());
95       });
96     return clazz.cast(this);
97   }
98
99   public T registerApplication(ComponentDto application, ComponentDto... appProjects) {
100     registerComponents(application);
101     registerComponents(appProjects);
102
103     var appProjectsUuid = Arrays.stream(appProjects)
104       .map(ComponentDto::uuid)
105       .collect(Collectors.toSet());
106     this.applicationProjects.put(application.uuid(), appProjectsUuid);
107
108     return clazz.cast(this);
109   }
110
111   public T registerApplication(ProjectDto application, ProjectDto... appProjects) {
112     registerProjects(application);
113     registerProjects(appProjects);
114
115     var appProjectsUuid = Arrays.stream(appProjects)
116       .map(ProjectDto::getUuid)
117       .collect(Collectors.toSet());
118     this.applicationProjects.put(application.getUuid(), appProjectsUuid);
119
120     return clazz.cast(this);
121   }
122
123   public T registerPortfolios(PortfolioDto... portfolios) {
124     Arrays.stream(portfolios)
125       .forEach(portfolio -> {
126         if (!portfolio.isPrivate()) {
127           this.projectUuidByPermission.put(UserRole.USER, portfolio.getUuid());
128           this.projectUuidByPermission.put(UserRole.CODEVIEWER, portfolio.getUuid());
129           this.projectPermissions.add(UserRole.USER);
130           this.projectPermissions.add(UserRole.CODEVIEWER);
131         }
132         this.projectUuidByComponentUuid.put(portfolio.getUuid(), portfolio.getUuid());
133       });
134     return clazz.cast(this);
135   }
136
137   public T registerPortfolioProjects(PortfolioDto portfolio, ProjectDto... portfolioProjects) {
138     registerPortfolios(portfolio);
139     registerProjects(portfolioProjects);
140
141     Set<String> portfolioProjectsUuid = Arrays.stream(portfolioProjects)
142       .map(ProjectDto::getUuid)
143       .collect(Collectors.toSet());
144
145     this.portfolioProjects.put(portfolio.getUuid(), portfolioProjectsUuid);
146
147     return clazz.cast(this);
148   }
149
150   public T addProjectPermission(String permission, ComponentDto... components) {
151     Arrays.stream(components).forEach(component -> {
152       checkArgument(
153         component.isPrivate() || !PUBLIC_PERMISSIONS.contains(permission),
154         "public component %s can't be granted public permission %s", component.uuid(), permission);
155     });
156     registerComponents(components);
157     this.projectPermissions.add(permission);
158     Arrays.stream(components)
159       .forEach(component -> this.projectUuidByPermission.put(permission, component.projectUuid()));
160     return clazz.cast(this);
161   }
162
163   public T addProjectPermission(String permission, ProjectDto... projects) {
164     Arrays.stream(projects).forEach(component -> {
165       checkArgument(
166         component.isPrivate() || !PUBLIC_PERMISSIONS.contains(permission),
167         "public component %s can't be granted public permission %s", component.getUuid(), permission);
168     });
169     registerProjects(projects);
170     this.projectPermissions.add(permission);
171     Arrays.stream(projects)
172       .forEach(project -> this.projectUuidByPermission.put(permission, project.getUuid()));
173     return clazz.cast(this);
174   }
175
176   public T addPortfolioPermission(String permission, PortfolioDto... portfolios) {
177     Arrays.stream(portfolios).forEach(component -> {
178       checkArgument(
179         component.isPrivate() || !PUBLIC_PERMISSIONS.contains(permission),
180         "public component %s can't be granted public permission %s", component.getUuid(), permission);
181     });
182     registerPortfolios(portfolios);
183     this.projectPermissions.add(permission);
184     Arrays.stream(portfolios)
185       .forEach(portfolio -> this.projectUuidByPermission.put(permission, portfolio.getUuid()));
186     return clazz.cast(this);
187   }
188
189   @Override
190   protected Optional<String> componentUuidToProjectUuid(String componentUuid) {
191     return Optional.ofNullable(projectUuidByComponentUuid.get(componentUuid));
192   }
193
194   @Override
195   protected boolean hasProjectUuidPermission(String permission, String projectUuid) {
196     return projectPermissions.contains(permission) && projectUuidByPermission.get(permission).contains(projectUuid);
197   }
198
199   @Override
200   protected boolean hasChildProjectsPermission(String permission, String applicationUuid) {
201     return applicationProjects.containsKey(applicationUuid) && applicationProjects.get(applicationUuid)
202       .stream()
203       .allMatch(projectUuid -> projectPermissions.contains(permission) && projectUuidByPermission.get(permission).contains(projectUuid));
204   }
205
206   @Override
207   protected boolean hasPortfolioChildProjectsPermission(String permission, String portfolioUuid) {
208     return portfolioProjects.containsKey(portfolioUuid) && portfolioProjects.get(portfolioUuid)
209       .stream()
210       .allMatch(projectUuid -> projectPermissions.contains(permission) && projectUuidByPermission.get(permission).contains(projectUuid));
211   }
212
213   public T setSystemAdministrator(boolean b) {
214     this.systemAdministrator = b;
215     return clazz.cast(this);
216   }
217
218   @Override
219   public boolean isSystemAdministrator() {
220     return systemAdministrator;
221   }
222
223   public T setResetPassword(boolean b) {
224     this.resetPassword = b;
225     return clazz.cast(this);
226   }
227
228   @Override
229   public boolean shouldResetPassword() {
230     return resetPassword;
231   }
232 }