You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

UserSession.java 8.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257
  1. /*
  2. * SonarQube
  3. * Copyright (C) 2009-2020 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.user;
  21. import java.util.Arrays;
  22. import java.util.Collection;
  23. import java.util.List;
  24. import java.util.Objects;
  25. import java.util.Optional;
  26. import javax.annotation.CheckForNull;
  27. import javax.annotation.concurrent.Immutable;
  28. import org.sonar.db.component.ComponentDto;
  29. import org.sonar.db.permission.OrganizationPermission;
  30. import org.sonar.db.project.ProjectDto;
  31. import org.sonar.db.user.GroupDto;
  32. import static java.util.Objects.requireNonNull;
  33. public interface UserSession {
  34. /**
  35. * Login of the authenticated user. Returns {@code null}
  36. * if {@link #isLoggedIn()} is {@code false}.
  37. */
  38. @CheckForNull
  39. String getLogin();
  40. /**
  41. * Uuid of the authenticated user. Returns {@code null}
  42. * if {@link #isLoggedIn()} is {@code false}.
  43. */
  44. @CheckForNull
  45. String getUuid();
  46. /**
  47. * Name of the authenticated user. Returns {@code null}
  48. * if {@link #isLoggedIn()} is {@code false}.
  49. */
  50. @CheckForNull
  51. String getName();
  52. /**
  53. * The groups that the logged-in user is member of. An empty
  54. * collection is returned if {@link #isLoggedIn()} is {@code false}.
  55. */
  56. Collection<GroupDto> getGroups();
  57. /**
  58. * This enum supports by name only the few providers for which specific code exists.
  59. */
  60. enum IdentityProvider {
  61. SONARQUBE("sonarqube"), GITHUB("github"), BITBUCKETCLOUD("bitbucket"), OTHER("other");
  62. String key;
  63. IdentityProvider(String key) {
  64. this.key = key;
  65. }
  66. public String getKey() {
  67. return key;
  68. }
  69. public static IdentityProvider getFromKey(String key) {
  70. return Arrays.stream(IdentityProvider.values())
  71. .filter(i -> i.getKey().equals(key))
  72. .findAny()
  73. .orElse(OTHER);
  74. }
  75. }
  76. /**
  77. * @return empty if user is anonymous
  78. */
  79. Optional<IdentityProvider> getIdentityProvider();
  80. @Immutable final class ExternalIdentity {
  81. private final String id;
  82. private final String login;
  83. public ExternalIdentity(String id, String login) {
  84. this.id = requireNonNull(id, "id can't be null");
  85. this.login = requireNonNull(login, "login can't be null");
  86. }
  87. public String getId() {
  88. return id;
  89. }
  90. public String getLogin() {
  91. return login;
  92. }
  93. @Override
  94. public String toString() {
  95. return "ExternalIdentity{" +
  96. "id='" + id + '\'' +
  97. ", login='" + login + '\'' +
  98. '}';
  99. }
  100. @Override
  101. public boolean equals(Object o) {
  102. if (this == o) {
  103. return true;
  104. }
  105. if (o == null || getClass() != o.getClass()) {
  106. return false;
  107. }
  108. ExternalIdentity that = (ExternalIdentity) o;
  109. return Objects.equals(id, that.id) && Objects.equals(login, that.login);
  110. }
  111. @Override
  112. public int hashCode() {
  113. return Objects.hash(id, login);
  114. }
  115. }
  116. /**
  117. * @return empty if {@link #getIdentityProvider()} returns empty or {@link IdentityProvider#SONARQUBE}
  118. */
  119. Optional<ExternalIdentity> getExternalIdentity();
  120. /**
  121. * Whether the user is logged-in or anonymous.
  122. */
  123. boolean isLoggedIn();
  124. /**
  125. * Whether the user has root privileges. If {@code true}, then user automatically
  126. * benefits from all the permissions on all organizations and projects.
  127. */
  128. boolean isRoot();
  129. /**
  130. * Ensures that {@link #isRoot()} returns {@code true} otherwise throws a
  131. * {@link org.sonar.server.exceptions.ForbiddenException}.
  132. */
  133. UserSession checkIsRoot();
  134. /**
  135. * Ensures that user is logged in otherwise throws {@link org.sonar.server.exceptions.UnauthorizedException}.
  136. */
  137. UserSession checkLoggedIn();
  138. /**
  139. * Returns {@code true} if the permission is granted on the organization, otherwise {@code false}.
  140. *
  141. * If the organization does not exist, then returns {@code false}.
  142. *
  143. * Always returns {@code true} if {@link #isRoot()} is {@code true}, even if
  144. * organization does not exist.
  145. */
  146. boolean hasPermission(OrganizationPermission permission);
  147. /**
  148. * Ensures that {@link #hasPermission(OrganizationPermission)} is {@code true},
  149. * otherwise throws a {@link org.sonar.server.exceptions.ForbiddenException}.
  150. */
  151. UserSession checkPermission(OrganizationPermission permission);
  152. /**
  153. * Returns {@code true} if the permission is granted to user on the component,
  154. * otherwise {@code false}.
  155. *
  156. * If the component does not exist, then returns {@code false}.
  157. *
  158. * Always returns {@code true} if {@link #isRoot()} is {@code true}, even if
  159. * component does not exist.
  160. *
  161. * If the permission is not granted, then the organization permission is _not_ checked.
  162. *
  163. * @param component non-null component.
  164. * @param permission project permission as defined by {@link org.sonar.server.permission.PermissionService}
  165. */
  166. boolean hasComponentPermission(String permission, ComponentDto component);
  167. boolean hasProjectPermission(String permission, ProjectDto project);
  168. /**
  169. * Using {@link #hasComponentPermission(String, ComponentDto)} is recommended
  170. * because it does not have to load project if the referenced component
  171. * is not a project.
  172. *
  173. * @deprecated use {@link #hasComponentPermission(String, ComponentDto)} instead
  174. */
  175. @Deprecated
  176. boolean hasComponentUuidPermission(String permission, String componentUuid);
  177. /**
  178. * Return the subset of specified components which the user has granted permission.
  179. * An empty list is returned if input is empty or if no components are allowed to be
  180. * accessed.
  181. * If the input is ordered, then the returned components are in the same order.
  182. * The duplicated components are returned duplicated too.
  183. */
  184. List<ComponentDto> keepAuthorizedComponents(String permission, Collection<ComponentDto> components);
  185. List<ProjectDto> keepAuthorizedProjects(String permission, Collection<ProjectDto> projects);
  186. /**
  187. * Ensures that {@link #hasComponentPermission(String, ComponentDto)} is {@code true},
  188. * otherwise throws a {@link org.sonar.server.exceptions.ForbiddenException}.
  189. */
  190. UserSession checkComponentPermission(String projectPermission, ComponentDto component);
  191. /**
  192. * Ensures that {@link #hasProjectPermission(String, ProjectDto)} is {@code true},
  193. * otherwise throws a {@link org.sonar.server.exceptions.ForbiddenException}.
  194. */
  195. UserSession checkProjectPermission(String projectPermission, ProjectDto project);
  196. /**
  197. * Ensures that {@link #hasComponentUuidPermission(String, String)} is {@code true},
  198. * otherwise throws a {@link org.sonar.server.exceptions.ForbiddenException}.
  199. *
  200. * @deprecated use {@link #checkComponentPermission(String, ComponentDto)} instead
  201. */
  202. @Deprecated
  203. UserSession checkComponentUuidPermission(String permission, String componentUuid);
  204. /**
  205. * Whether user can administrate system, for example for using cross-organizations services
  206. * like update center, system info or management of users.
  207. *
  208. * Returns {@code true} if:
  209. * <ul>
  210. * <li>{@link #isRoot()} is {@code true}</li>
  211. * <li>organization feature is disabled and user is administrator of the (single) default organization</li>
  212. * </ul>
  213. */
  214. boolean isSystemAdministrator();
  215. /**
  216. * Ensures that {@link #isSystemAdministrator()} is {@code true},
  217. * otherwise throws {@link org.sonar.server.exceptions.ForbiddenException}.
  218. */
  219. UserSession checkIsSystemAdministrator();
  220. }