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.

SearchActionTest.java 39KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901
  1. /*
  2. * SonarQube
  3. * Copyright (C) 2009-2019 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.issue.ws;
  21. import com.google.gson.JsonElement;
  22. import com.google.gson.JsonParser;
  23. import java.time.Clock;
  24. import java.util.Arrays;
  25. import java.util.Collections;
  26. import org.junit.Before;
  27. import org.junit.Rule;
  28. import org.junit.Test;
  29. import org.junit.rules.ExpectedException;
  30. import org.sonar.api.config.internal.MapSettings;
  31. import org.sonar.api.resources.Languages;
  32. import org.sonar.api.rule.RuleStatus;
  33. import org.sonar.api.rules.RuleType;
  34. import org.sonar.api.server.ws.WebService;
  35. import org.sonar.api.utils.Durations;
  36. import org.sonar.api.utils.System2;
  37. import org.sonar.db.DbClient;
  38. import org.sonar.db.DbSession;
  39. import org.sonar.db.DbTester;
  40. import org.sonar.db.component.ComponentDto;
  41. import org.sonar.db.component.ComponentTesting;
  42. import org.sonar.db.issue.IssueChangeDto;
  43. import org.sonar.db.issue.IssueDto;
  44. import org.sonar.db.issue.IssueTesting;
  45. import org.sonar.db.organization.OrganizationDto;
  46. import org.sonar.db.permission.GroupPermissionDto;
  47. import org.sonar.db.protobuf.DbCommons;
  48. import org.sonar.db.protobuf.DbIssues;
  49. import org.sonar.db.rule.RuleDefinitionDto;
  50. import org.sonar.db.rule.RuleDto;
  51. import org.sonar.db.rule.RuleTesting;
  52. import org.sonar.db.user.UserDto;
  53. import org.sonar.server.es.EsTester;
  54. import org.sonar.server.es.SearchOptions;
  55. import org.sonar.server.es.StartupIndexer;
  56. import org.sonar.server.issue.IssueFieldsSetter;
  57. import org.sonar.server.issue.TransitionService;
  58. import org.sonar.server.issue.index.IssueIndex;
  59. import org.sonar.server.issue.index.IssueIndexer;
  60. import org.sonar.server.issue.index.IssueIteratorFactory;
  61. import org.sonar.server.issue.index.IssueQuery;
  62. import org.sonar.server.issue.index.IssueQueryFactory;
  63. import org.sonar.server.issue.workflow.FunctionExecutor;
  64. import org.sonar.server.issue.workflow.IssueWorkflow;
  65. import org.sonar.server.permission.index.PermissionIndexer;
  66. import org.sonar.server.permission.index.WebAuthorizationTypeSupport;
  67. import org.sonar.server.tester.UserSessionRule;
  68. import org.sonar.server.ws.TestResponse;
  69. import org.sonar.server.ws.WsActionTester;
  70. import org.sonar.server.ws.WsResponseCommonFormat;
  71. import org.sonarqube.ws.Common;
  72. import org.sonarqube.ws.Common.Severity;
  73. import org.sonarqube.ws.Issues;
  74. import org.sonarqube.ws.Issues.Issue;
  75. import org.sonarqube.ws.Issues.SearchWsResponse;
  76. import static java.util.Arrays.asList;
  77. import static java.util.Collections.singletonList;
  78. import static org.assertj.core.api.Assertions.assertThat;
  79. import static org.assertj.core.groups.Tuple.tuple;
  80. import static org.junit.rules.ExpectedException.none;
  81. import static org.sonar.api.issue.Issue.RESOLUTION_FIXED;
  82. import static org.sonar.api.issue.Issue.STATUS_RESOLVED;
  83. import static org.sonar.api.server.ws.WebService.Param.FACETS;
  84. import static org.sonar.api.utils.DateUtils.formatDateTime;
  85. import static org.sonar.api.utils.DateUtils.parseDate;
  86. import static org.sonar.api.utils.DateUtils.parseDateTime;
  87. import static org.sonar.api.web.UserRole.ISSUE_ADMIN;
  88. import static org.sonar.db.component.ComponentTesting.newFileDto;
  89. import static org.sonar.db.issue.IssueTesting.newDto;
  90. import static org.sonar.server.tester.UserSessionRule.standalone;
  91. import static org.sonarqube.ws.client.component.ComponentsWsParameters.PARAM_BRANCH;
  92. import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_ADDITIONAL_FIELDS;
  93. import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_COMPONENT_KEYS;
  94. import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_CREATED_AFTER;
  95. import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_HIDE_COMMENTS;
  96. import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_PAGE_INDEX;
  97. import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_PAGE_SIZE;
  98. import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_RULES;
  99. public class SearchActionTest {
  100. @Rule
  101. public UserSessionRule userSession = standalone();
  102. @Rule
  103. public DbTester db = DbTester.create();
  104. @Rule
  105. public EsTester es = EsTester.create();
  106. @Rule
  107. public ExpectedException expectedException = none();
  108. private DbClient dbClient = db.getDbClient();
  109. private DbSession session = db.getSession();
  110. private IssueIndex issueIndex = new IssueIndex(es.client(), System2.INSTANCE, userSession, new WebAuthorizationTypeSupport(userSession));
  111. private IssueIndexer issueIndexer = new IssueIndexer(es.client(), dbClient, new IssueIteratorFactory(dbClient));
  112. private IssueQueryFactory issueQueryFactory = new IssueQueryFactory(dbClient, Clock.systemUTC(), userSession);
  113. private IssueFieldsSetter issueFieldsSetter = new IssueFieldsSetter();
  114. private IssueWorkflow issueWorkflow = new IssueWorkflow(new FunctionExecutor(issueFieldsSetter), issueFieldsSetter);
  115. private SearchResponseLoader searchResponseLoader = new SearchResponseLoader(userSession, dbClient, new TransitionService(userSession, issueWorkflow));
  116. private Languages languages = new Languages();
  117. private SearchResponseFormat searchResponseFormat = new SearchResponseFormat(new Durations(), new WsResponseCommonFormat(languages), languages, new AvatarResolverImpl());
  118. private WsActionTester ws = new WsActionTester(new SearchAction(userSession, issueIndex, issueQueryFactory, searchResponseLoader, searchResponseFormat,
  119. new MapSettings().asConfig(), System2.INSTANCE, dbClient));
  120. private StartupIndexer permissionIndexer = new PermissionIndexer(dbClient, es.client(), issueIndexer);
  121. @Before
  122. public void setUp() {
  123. issueWorkflow.start();
  124. }
  125. @Test
  126. public void response_contains_all_fields_except_additional_fields() {
  127. OrganizationDto organization = db.organizations().insert();
  128. UserDto user = db.users().insertUser();
  129. db.organizations().addMember(organization, user);
  130. userSession.logIn(user);
  131. ComponentDto project = db.components().insertPublicProject(organization);
  132. indexPermissions();
  133. ComponentDto file = db.components().insertComponent(newFileDto(project));
  134. UserDto simon = db.users().insertUser();
  135. RuleDefinitionDto rule = newRule().getDefinition();
  136. IssueDto issue = db.issues().insert(rule, project, file, i -> i
  137. .setEffort(10L)
  138. .setLine(42)
  139. .setChecksum("a227e508d6646b55a086ee11d63b21e9")
  140. .setMessage("the message")
  141. .setStatus(STATUS_RESOLVED)
  142. .setResolution(RESOLUTION_FIXED)
  143. .setSeverity("MAJOR")
  144. .setAuthorLogin("John")
  145. .setAssigneeUuid(simon.getUuid())
  146. .setTags(asList("bug", "owasp"))
  147. .setIssueCreationDate(parseDate("2014-09-03"))
  148. .setIssueUpdateDate(parseDate("2017-12-04")));
  149. indexIssues();
  150. SearchWsResponse response = ws.newRequest()
  151. .executeProtobuf(SearchWsResponse.class);
  152. assertThat(response.getIssuesList())
  153. .extracting(
  154. Issue::getOrganization, Issue::getKey, Issue::getRule, Issue::getSeverity, Issue::getComponent, Issue::getResolution, Issue::getStatus, Issue::getMessage, Issue::getEffort,
  155. Issue::getAssignee, Issue::getAuthor, Issue::getLine, Issue::getHash, Issue::getTagsList, Issue::getCreationDate, Issue::getUpdateDate)
  156. .containsExactlyInAnyOrder(
  157. tuple(organization.getKey(), issue.getKey(), rule.getKey().toString(), Severity.MAJOR, file.getKey(), RESOLUTION_FIXED, STATUS_RESOLVED, "the message", "10min",
  158. simon.getLogin(), "John", 42, "a227e508d6646b55a086ee11d63b21e9", asList("bug", "owasp"), formatDateTime(issue.getIssueCreationDate()),
  159. formatDateTime(issue.getIssueUpdateDate())));
  160. }
  161. @Test
  162. public void issue_on_external_rule() {
  163. OrganizationDto organization = db.organizations().insert();
  164. ComponentDto project = db.components().insertPublicProject(organization);
  165. indexPermissions();
  166. ComponentDto file = db.components().insertComponent(newFileDto(project));
  167. RuleDefinitionDto rule = db.rules().insert(RuleTesting.EXTERNAL_XOO, r -> r.setIsExternal(true).setLanguage("xoo"));
  168. IssueDto issue = db.issues().insert(rule, project, file);
  169. indexIssues();
  170. SearchWsResponse response = ws.newRequest()
  171. .executeProtobuf(SearchWsResponse.class);
  172. assertThat(response.getIssuesList())
  173. .extracting(Issue::getKey, Issue::getRule, Issue::getExternalRuleEngine)
  174. .containsExactlyInAnyOrder(tuple(issue.getKey(), rule.getKey().toString(), "xoo"));
  175. }
  176. @Test
  177. public void hide_author_if_not_member_of_organization() {
  178. UserDto user = db.users().insertUser();
  179. userSession.logIn(user);
  180. OrganizationDto organization = db.organizations().insert();
  181. ComponentDto project = db.components().insertPublicProject(organization);
  182. indexPermissions();
  183. ComponentDto file = db.components().insertComponent(newFileDto(project));
  184. RuleDefinitionDto rule = newRule().getDefinition();
  185. IssueDto issue = db.issues().insert(rule, project, file, i -> i.setAuthorLogin("John"));
  186. indexIssues();
  187. SearchWsResponse response = ws.newRequest()
  188. .executeProtobuf(SearchWsResponse.class);
  189. assertThat(response.getIssuesList())
  190. .extracting(Issue::getKey, Issue::hasAuthor)
  191. .containsExactlyInAnyOrder(tuple(issue.getKey(), false));
  192. }
  193. @Test
  194. public void issue_with_cross_file_locations() {
  195. ComponentDto project = db.components().insertPublicProject();
  196. indexPermissions();
  197. ComponentDto file = db.components().insertComponent(newFileDto(project));
  198. ComponentDto anotherFile = db.components().insertComponent(newFileDto(project));
  199. DbIssues.Locations.Builder locations = DbIssues.Locations.newBuilder().addFlow(DbIssues.Flow.newBuilder().addAllLocation(Arrays.asList(
  200. DbIssues.Location.newBuilder()
  201. .setComponentId(file.uuid())
  202. .setMsg("FLOW MESSAGE")
  203. .setTextRange(DbCommons.TextRange.newBuilder()
  204. .setStartLine(1)
  205. .setEndLine(1)
  206. .setStartOffset(0)
  207. .setEndOffset(12)
  208. .build())
  209. .build(),
  210. DbIssues.Location.newBuilder()
  211. .setComponentId(anotherFile.uuid())
  212. .setMsg("ANOTHER FLOW MESSAGE")
  213. .setTextRange(DbCommons.TextRange.newBuilder()
  214. .setStartLine(1)
  215. .setEndLine(1)
  216. .setStartOffset(0)
  217. .setEndOffset(12)
  218. .build())
  219. .build(),
  220. DbIssues.Location.newBuilder()
  221. // .setComponentId(no component id set)
  222. .setMsg("FLOW MESSAGE WITHOUT FILE UUID")
  223. .setTextRange(DbCommons.TextRange.newBuilder()
  224. .setStartLine(1)
  225. .setEndLine(1)
  226. .setStartOffset(0)
  227. .setEndOffset(12)
  228. .build())
  229. .build())));
  230. RuleDefinitionDto rule = newRule().getDefinition();
  231. db.issues().insert(rule, project, file, i -> i.setLocations(locations.build()));
  232. indexIssues();
  233. SearchWsResponse result = ws.newRequest().executeProtobuf(SearchWsResponse.class);
  234. assertThat(result.getIssuesCount()).isEqualTo(1);
  235. assertThat(result.getIssues(0).getFlows(0).getLocationsList()).extracting(Issues.Location::getComponent, Issues.Location::getMsg)
  236. .containsExactlyInAnyOrder(
  237. tuple(file.getKey(), "FLOW MESSAGE"),
  238. tuple(anotherFile.getKey(), "ANOTHER FLOW MESSAGE"),
  239. tuple(file.getKey(), "FLOW MESSAGE WITHOUT FILE UUID"));
  240. }
  241. @Test
  242. public void issue_with_comments() {
  243. UserDto john = db.users().insertUser(u -> u.setLogin("john").setName("John"));
  244. UserDto fabrice = db.users().insertUser(u -> u.setLogin("fabrice").setName("Fabrice").setEmail("fabrice@email.com"));
  245. ComponentDto project = db.components().insertPublicProject();
  246. indexPermissions();
  247. ComponentDto file = db.components().insertComponent(newFileDto(project));
  248. RuleDefinitionDto rule = newRule().getDefinition();
  249. IssueDto issue = db.issues().insert(rule, project, file, i -> i.setKee("82fd47d4-b650-4037-80bc-7b112bd4eac2"));
  250. dbClient.issueChangeDao().insert(session,
  251. new IssueChangeDto().setIssueKey(issue.getKey())
  252. .setKey("COMMENT-ABCD")
  253. .setChangeData("*My comment*")
  254. .setChangeType(IssueChangeDto.TYPE_COMMENT)
  255. .setUserUuid(john.getUuid())
  256. .setIssueChangeCreationDate(parseDateTime("2014-09-09T12:00:00+0000").getTime()));
  257. dbClient.issueChangeDao().insert(session,
  258. new IssueChangeDto().setIssueKey(issue.getKey())
  259. .setKey("COMMENT-ABCE")
  260. .setChangeData("Another comment")
  261. .setChangeType(IssueChangeDto.TYPE_COMMENT)
  262. .setUserUuid(fabrice.getUuid())
  263. .setIssueChangeCreationDate(parseDateTime("2014-09-10T12:00:00+0000").getTime()));
  264. session.commit();
  265. indexIssues();
  266. userSession.logIn(john);
  267. ws.newRequest()
  268. .setParam("additionalFields", "comments,users")
  269. .execute()
  270. .assertJson(this.getClass(), "issue_with_comments.json");
  271. }
  272. @Test
  273. public void issue_with_comment_hidden() {
  274. UserDto john = db.users().insertUser(u -> u.setLogin("john").setName("John").setEmail("john@email.com"));
  275. UserDto fabrice = db.users().insertUser(u -> u.setLogin("fabrice").setName("Fabrice").setEmail("fabrice@email.com"));
  276. ComponentDto project = db.components().insertPublicProject();
  277. indexPermissions();
  278. ComponentDto file = db.components().insertComponent(newFileDto(project));
  279. RuleDefinitionDto rule = newRule().getDefinition();
  280. IssueDto issue = db.issues().insert(rule, project, file, i -> i.setKee("82fd47d4-b650-4037-80bc-7b112bd4eac2"));
  281. dbClient.issueChangeDao().insert(session,
  282. new IssueChangeDto().setIssueKey(issue.getKey())
  283. .setKey("COMMENT-ABCD")
  284. .setChangeData("*My comment*")
  285. .setChangeType(IssueChangeDto.TYPE_COMMENT)
  286. .setUserUuid(john.getUuid())
  287. .setCreatedAt(parseDateTime("2014-09-09T12:00:00+0000").getTime()));
  288. dbClient.issueChangeDao().insert(session,
  289. new IssueChangeDto().setIssueKey(issue.getKey())
  290. .setKey("COMMENT-ABCE")
  291. .setChangeData("Another comment")
  292. .setChangeType(IssueChangeDto.TYPE_COMMENT)
  293. .setUserUuid(fabrice.getUuid())
  294. .setCreatedAt(parseDateTime("2014-09-10T19:10:03+0000").getTime()));
  295. session.commit();
  296. indexIssues();
  297. userSession.logIn(john);
  298. SearchWsResponse response = ws.newRequest()
  299. .setParam(PARAM_HIDE_COMMENTS, "true")
  300. .executeProtobuf(SearchWsResponse.class);
  301. assertThat(response.getIssuesList())
  302. .extracting(Issue::getKey, i -> i.getComments().getCommentsList())
  303. .containsExactlyInAnyOrder(tuple(issue.getKey(), Collections.emptyList()));
  304. }
  305. @Test
  306. public void load_additional_fields() {
  307. UserDto simon = db.users().insertUser(u -> u.setLogin("simon").setName("Simon").setEmail("simon@email.com"));
  308. ComponentDto project = db.components().insertPublicProject();
  309. indexPermissions();
  310. ComponentDto file = db.components().insertComponent(newFileDto(project));
  311. RuleDefinitionDto rule = newRule().getDefinition();
  312. db.issues().insert(rule, project, file, i -> i.setAssigneeUuid(simon.getUuid()));
  313. indexIssues();
  314. userSession.logIn("john");
  315. ws.newRequest()
  316. .setParam("additionalFields", "_all").execute()
  317. .assertJson(this.getClass(), "load_additional_fields.json");
  318. }
  319. @Test
  320. public void load_additional_fields_with_issue_admin_permission() {
  321. UserDto simon = db.users().insertUser(u -> u.setLogin("simon").setName("Simon").setEmail("simon@email.com"));
  322. UserDto fabrice = db.users().insertUser(u -> u.setLogin("fabrice").setName("Fabrice").setEmail("fabrice@email.com"));
  323. OrganizationDto organization = db.organizations().insert(o -> o.setKey("my-org-1"));
  324. ComponentDto project = db.components().insertComponent(ComponentTesting.newPublicProjectDto(organization, "PROJECT_ID").setDbKey("PROJECT_KEY").setLanguage("java"));
  325. grantPermissionToAnyone(project, ISSUE_ADMIN);
  326. indexPermissions();
  327. ComponentDto file = db.components().insertComponent(newFileDto(project, null, "FILE_ID").setDbKey("FILE_KEY").setLanguage("js"));
  328. IssueDto issue = newDto(newRule(), file, project)
  329. .setKee("82fd47d4-b650-4037-80bc-7b112bd4eac2")
  330. .setAuthorLogin(fabrice.getLogin())
  331. .setAssigneeUuid(simon.getUuid());
  332. dbClient.issueDao().insert(session, issue);
  333. session.commit();
  334. indexIssues();
  335. userSession.logIn("john")
  336. .addProjectPermission(ISSUE_ADMIN, project); // granted by Anyone
  337. ws.newRequest()
  338. .setParam("additionalFields", "_all").execute()
  339. .assertJson(this.getClass(), "load_additional_fields_with_issue_admin_permission.json");
  340. }
  341. @Test
  342. public void search_by_rule_key() {
  343. RuleDto rule = newRule();
  344. OrganizationDto organization = db.organizations().insert(o -> o.setKey("my-org-1"));
  345. ComponentDto project = db.components().insertComponent(ComponentTesting.newPublicProjectDto(organization, "PROJECT_ID").setDbKey("PROJECT_KEY").setLanguage("java"));
  346. ComponentDto file = db.components().insertComponent(newFileDto(project, null, "FILE_ID").setDbKey("FILE_KEY").setLanguage("java"));
  347. IssueDto issue = IssueTesting.newIssue(rule.getDefinition(), project, file);
  348. dbClient.issueDao().insert(session, issue);
  349. session.commit();
  350. indexIssues();
  351. userSession.logIn("john")
  352. .addProjectPermission(ISSUE_ADMIN, project); // granted by Anyone
  353. indexPermissions();
  354. TestResponse execute = ws.newRequest()
  355. .setParam(PARAM_RULES, rule.getKey().toString())
  356. .setParam("additionalFields", "_all")
  357. .execute();
  358. execute.assertJson(this.getClass(), "result_for_rule_search.json");
  359. }
  360. @Test
  361. public void issue_on_removed_file() {
  362. RuleDto rule = newRule();
  363. OrganizationDto organization = db.organizations().insert(o -> o.setKey("my-org-2"));
  364. ComponentDto project = db.components().insertComponent(ComponentTesting.newPublicProjectDto(organization, "PROJECT_ID").setDbKey("PROJECT_KEY"));
  365. indexPermissions();
  366. ComponentDto removedFile = db.components().insertComponent(newFileDto(project, null).setUuid("REMOVED_FILE_ID")
  367. .setDbKey("REMOVED_FILE_KEY")
  368. .setEnabled(false));
  369. IssueDto issue = newDto(rule, removedFile, project)
  370. .setKee("82fd47d4-b650-4037-80bc-7b112bd4eac2")
  371. .setComponent(removedFile)
  372. .setStatus("OPEN").setResolution("OPEN")
  373. .setSeverity("MAJOR")
  374. .setIssueCreationDate(parseDateTime("2014-09-04T00:00:00+0100"))
  375. .setIssueUpdateDate(parseDateTime("2017-12-04T00:00:00+0100"));
  376. dbClient.issueDao().insert(session, issue);
  377. session.commit();
  378. indexIssues();
  379. ws.newRequest()
  380. .execute()
  381. .assertJson(this.getClass(), "issue_on_removed_file.json");
  382. }
  383. @Test
  384. public void apply_paging_with_one_component() {
  385. RuleDto rule = newRule();
  386. OrganizationDto organization = db.organizations().insert(o -> o.setKey("my-org-2"));
  387. ComponentDto project = db.components().insertComponent(ComponentTesting.newPublicProjectDto(organization, "PROJECT_ID").setDbKey("PROJECT_KEY"));
  388. indexPermissions();
  389. ComponentDto file = db.components().insertComponent(newFileDto(project, null, "FILE_ID").setDbKey("FILE_KEY"));
  390. for (int i = 0; i < SearchOptions.MAX_LIMIT + 1; i++) {
  391. IssueDto issue = newDto(rule, file, project).setAssigneeUuid(null);
  392. dbClient.issueDao().insert(session, issue);
  393. }
  394. session.commit();
  395. indexIssues();
  396. ws.newRequest().setParam(PARAM_COMPONENT_KEYS, file.getKey()).execute()
  397. .assertJson(this.getClass(), "apply_paging_with_one_component.json");
  398. }
  399. @Test
  400. public void components_contains_sub_projects() {
  401. OrganizationDto organization = db.organizations().insert(o -> o.setKey("my-org-1"));
  402. ComponentDto project = db.components().insertComponent(ComponentTesting.newPublicProjectDto(organization, "PROJECT_ID").setDbKey("ProjectHavingModule"));
  403. indexPermissions();
  404. ComponentDto module = db.components().insertComponent(ComponentTesting.newModuleDto(project).setDbKey("ModuleHavingFile"));
  405. ComponentDto file = db.components().insertComponent(newFileDto(module, null, "BCDE").setDbKey("FileLinkedToModule"));
  406. IssueDto issue = newDto(newRule(), file, project);
  407. dbClient.issueDao().insert(session, issue);
  408. session.commit();
  409. indexIssues();
  410. ws.newRequest().setParam(PARAM_ADDITIONAL_FIELDS, "_all").execute()
  411. .assertJson(this.getClass(), "components_contains_sub_projects.json");
  412. }
  413. @Test
  414. public void filter_by_assigned_to_me() {
  415. UserDto john = db.users().insertUser(u -> u.setLogin("john").setName("John").setEmail("john@email.com"));
  416. UserDto alice = db.users().insertUser(u -> u.setLogin("alice").setName("Alice").setEmail("alice@email.com"));
  417. OrganizationDto organization = db.organizations().insert();
  418. ComponentDto project = db.components().insertComponent(ComponentTesting.newPublicProjectDto(organization, "PROJECT_ID").setDbKey("PROJECT_KEY"));
  419. indexPermissions();
  420. ComponentDto file = db.components().insertComponent(newFileDto(project, null, "FILE_ID").setDbKey("FILE_KEY"));
  421. RuleDto rule = newRule();
  422. IssueDto issue1 = newDto(rule, file, project)
  423. .setIssueCreationDate(parseDate("2014-09-04"))
  424. .setIssueUpdateDate(parseDate("2017-12-04"))
  425. .setEffort(10L)
  426. .setStatus("OPEN")
  427. .setKee("82fd47d4-b650-4037-80bc-7b112bd4eac2")
  428. .setSeverity("MAJOR")
  429. .setAssigneeUuid(john.getUuid());
  430. IssueDto issue2 = newDto(rule, file, project)
  431. .setIssueCreationDate(parseDate("2014-09-04"))
  432. .setIssueUpdateDate(parseDate("2017-12-04"))
  433. .setEffort(10L)
  434. .setStatus("OPEN")
  435. .setKee("7b112bd4-b650-4037-80bc-82fd47d4eac2")
  436. .setSeverity("MAJOR")
  437. .setAssigneeUuid(alice.getUuid());
  438. IssueDto issue3 = newDto(rule, file, project)
  439. .setIssueCreationDate(parseDate("2014-09-04"))
  440. .setIssueUpdateDate(parseDate("2017-12-04"))
  441. .setEffort(10L)
  442. .setStatus("OPEN")
  443. .setKee("82fd47d4-4037-b650-80bc-7b112bd4eac2")
  444. .setSeverity("MAJOR")
  445. .setAssigneeUuid(null);
  446. dbClient.issueDao().insert(session, issue1, issue2, issue3);
  447. session.commit();
  448. indexIssues();
  449. userSession.logIn(john);
  450. ws.newRequest()
  451. .setParam("resolved", "false")
  452. .setParam("assignees", "__me__")
  453. .setParam(FACETS, "assignees,assigned_to_me")
  454. .execute()
  455. .assertJson(this.getClass(), "filter_by_assigned_to_me.json");
  456. }
  457. @Test
  458. public void return_empty_when_login_is_unknown() {
  459. UserDto john = db.users().insertUser(u -> u.setLogin("john").setName("John").setEmail("john@email.com"));
  460. UserDto alice = db.users().insertUser(u -> u.setLogin("alice").setName("Alice").setEmail("alice@email.com"));
  461. OrganizationDto organization = db.organizations().insert();
  462. ComponentDto project = db.components().insertComponent(ComponentTesting.newPublicProjectDto(organization, "PROJECT_ID").setDbKey("PROJECT_KEY"));
  463. indexPermissions();
  464. ComponentDto file = db.components().insertComponent(newFileDto(project, null, "FILE_ID").setDbKey("FILE_KEY"));
  465. RuleDto rule = newRule();
  466. IssueDto issue1 = newDto(rule, file, project)
  467. .setIssueCreationDate(parseDate("2014-09-04"))
  468. .setIssueUpdateDate(parseDate("2017-12-04"))
  469. .setEffort(10L)
  470. .setStatus("OPEN")
  471. .setKee("82fd47d4-b650-4037-80bc-7b112bd4eac2")
  472. .setSeverity("MAJOR")
  473. .setAssigneeUuid(john.getUuid());
  474. IssueDto issue2 = newDto(rule, file, project)
  475. .setIssueCreationDate(parseDate("2014-09-04"))
  476. .setIssueUpdateDate(parseDate("2017-12-04"))
  477. .setEffort(10L)
  478. .setStatus("OPEN")
  479. .setKee("7b112bd4-b650-4037-80bc-82fd47d4eac2")
  480. .setSeverity("MAJOR")
  481. .setAssigneeUuid(alice.getUuid());
  482. IssueDto issue3 = newDto(rule, file, project)
  483. .setIssueCreationDate(parseDate("2014-09-04"))
  484. .setIssueUpdateDate(parseDate("2017-12-04"))
  485. .setEffort(10L)
  486. .setStatus("OPEN")
  487. .setKee("82fd47d4-4037-b650-80bc-7b112bd4eac2")
  488. .setSeverity("MAJOR")
  489. .setAssigneeUuid(null);
  490. dbClient.issueDao().insert(session, issue1, issue2, issue3);
  491. session.commit();
  492. indexIssues();
  493. userSession.logIn(john);
  494. SearchWsResponse response = ws.newRequest()
  495. .setParam("resolved", "false")
  496. .setParam("assignees", "unknown")
  497. .setParam(FACETS, "assignees")
  498. .executeProtobuf(SearchWsResponse.class);
  499. assertThat(response.getIssuesList()).isEmpty();
  500. }
  501. @Test
  502. public void filter_by_assigned_to_me_when_not_authenticate() {
  503. UserDto poy = db.users().insertUser(u -> u.setLogin("poy").setName("poypoy").setEmail("poypoy@email.com"));
  504. userSession.logIn(poy);
  505. UserDto alice = db.users().insertUser(u -> u.setLogin("alice").setName("Alice").setEmail("alice@email.com"));
  506. UserDto john = db.users().insertUser(u -> u.setLogin("john").setName("John").setEmail("john@email.com"));
  507. OrganizationDto organization = db.organizations().insert(o -> o.setKey("my-org-1"));
  508. ComponentDto project = db.components().insertComponent(ComponentTesting.newPublicProjectDto(organization, "PROJECT_ID").setDbKey("PROJECT_KEY"));
  509. indexPermissions();
  510. ComponentDto file = db.components().insertComponent(newFileDto(project, null, "FILE_ID").setDbKey("FILE_KEY"));
  511. RuleDto rule = newRule();
  512. IssueDto issue1 = newDto(rule, file, project)
  513. .setStatus("OPEN")
  514. .setKee("82fd47d4-b650-4037-80bc-7b112bd4eac2")
  515. .setAssigneeUuid(john.getUuid());
  516. IssueDto issue2 = newDto(rule, file, project)
  517. .setStatus("OPEN")
  518. .setKee("7b112bd4-b650-4037-80bc-82fd47d4eac2")
  519. .setAssigneeUuid(alice.getUuid());
  520. IssueDto issue3 = newDto(rule, file, project)
  521. .setStatus("OPEN")
  522. .setKee("82fd47d4-4037-b650-80bc-7b112bd4eac2")
  523. .setAssigneeUuid(null);
  524. dbClient.issueDao().insert(session, issue1, issue2, issue3);
  525. session.commit();
  526. indexIssues();
  527. ws.newRequest()
  528. .setParam("resolved", "false")
  529. .setParam("assignees", "__me__")
  530. .execute()
  531. .assertJson(this.getClass(), "empty_result.json");
  532. }
  533. @Test
  534. public void search_by_author() {
  535. ComponentDto project = db.components().insertPublicProject();
  536. ComponentDto file = db.components().insertComponent(newFileDto(project, null));
  537. RuleDefinitionDto rule = db.rules().insert();
  538. IssueDto issue1 = db.issues().insert(rule, project, file, i -> i.setAuthorLogin("leia"));
  539. IssueDto issue2 = db.issues().insert(rule, project, file, i -> i.setAuthorLogin("luke"));
  540. IssueDto issue3 = db.issues().insert(rule, project, file, i -> i.setAuthorLogin("han, solo"));
  541. indexPermissions();
  542. indexIssues();
  543. SearchWsResponse response = ws.newRequest()
  544. .setMultiParam("author", asList("leia", "han, solo"))
  545. .setParam(FACETS, "author")
  546. .executeProtobuf(SearchWsResponse.class);
  547. assertThat(response.getIssuesList())
  548. .extracting(Issue::getKey)
  549. .containsExactlyInAnyOrder(issue1.getKey(), issue3.getKey());
  550. Common.Facet facet = response.getFacets().getFacetsList().get(0);
  551. assertThat(facet.getProperty()).isEqualTo("author");
  552. assertThat(facet.getValuesList())
  553. .extracting(Common.FacetValue::getVal, Common.FacetValue::getCount)
  554. .containsExactlyInAnyOrder(
  555. tuple("leia", 1L),
  556. tuple("luke", 1L),
  557. tuple("han, solo", 1L));
  558. assertThat(ws.newRequest()
  559. .setMultiParam("author", singletonList("unknown"))
  560. .executeProtobuf(SearchWsResponse.class).getIssuesList())
  561. .isEmpty();
  562. }
  563. @Test
  564. public void search_by_deprecated_authors_parameter() {
  565. ComponentDto project = db.components().insertPublicProject();
  566. ComponentDto file = db.components().insertComponent(newFileDto(project, null));
  567. RuleDefinitionDto rule = db.rules().insert();
  568. IssueDto issue1 = db.issues().insert(rule, project, file, i -> i.setAuthorLogin("leia"));
  569. IssueDto issue2 = db.issues().insert(rule, project, file, i -> i.setAuthorLogin("luke"));
  570. indexPermissions();
  571. indexIssues();
  572. SearchWsResponse response = ws.newRequest()
  573. .setParam("authors", "leia")
  574. .setParam(FACETS, "authors")
  575. .executeProtobuf(SearchWsResponse.class);
  576. assertThat(response.getIssuesList()).extracting(Issue::getKey).containsExactlyInAnyOrder(issue1.getKey());
  577. Common.Facet facet = response.getFacets().getFacetsList().get(0);
  578. assertThat(facet.getProperty()).isEqualTo("authors");
  579. assertThat(facet.getValuesList())
  580. .extracting(Common.FacetValue::getVal, Common.FacetValue::getCount)
  581. .containsExactlyInAnyOrder(
  582. tuple("leia", 1L),
  583. tuple("luke", 1L));
  584. // Deprecated parameter 'authors' will be ignored if new parameter 'author' is set
  585. assertThat(ws.newRequest()
  586. .setMultiParam("author", singletonList("luke"))
  587. // This parameter will be ignored
  588. .setParam("authors", "leia")
  589. .executeProtobuf(SearchWsResponse.class).getIssuesList())
  590. .extracting(Issue::getKey)
  591. .containsExactlyInAnyOrder(issue2.getKey());
  592. }
  593. @Test
  594. public void sort_by_updated_at() {
  595. RuleDto rule = newRule();
  596. OrganizationDto organization = db.organizations().insert(o -> o.setKey("my-org-2"));
  597. ComponentDto project = db.components().insertComponent(ComponentTesting.newPublicProjectDto(organization, "PROJECT_ID").setDbKey("PROJECT_KEY"));
  598. indexPermissions();
  599. ComponentDto file = db.components().insertComponent(newFileDto(project, null, "FILE_ID").setDbKey("FILE_KEY"));
  600. dbClient.issueDao().insert(session, newDto(rule, file, project)
  601. .setKee("82fd47d4-b650-4037-80bc-7b112bd4eac1")
  602. .setIssueUpdateDate(parseDateTime("2014-11-02T00:00:00+0100")));
  603. dbClient.issueDao().insert(session, newDto(rule, file, project)
  604. .setKee("82fd47d4-b650-4037-80bc-7b112bd4eac2")
  605. .setIssueUpdateDate(parseDateTime("2014-11-01T00:00:00+0100")));
  606. dbClient.issueDao().insert(session, newDto(rule, file, project)
  607. .setKee("82fd47d4-b650-4037-80bc-7b112bd4eac3")
  608. .setIssueUpdateDate(parseDateTime("2014-11-03T00:00:00+0100")));
  609. session.commit();
  610. indexIssues();
  611. TestResponse response = ws.newRequest()
  612. .setParam("sort", IssueQuery.SORT_BY_UPDATE_DATE)
  613. .setParam("asc", "false")
  614. .execute();
  615. JsonElement parse = new JsonParser().parse(response.getInput());
  616. assertThat(parse.getAsJsonObject().get("issues").getAsJsonArray())
  617. .extracting(o -> o.getAsJsonObject().get("key").getAsString())
  618. .containsExactly("82fd47d4-b650-4037-80bc-7b112bd4eac3", "82fd47d4-b650-4037-80bc-7b112bd4eac1", "82fd47d4-b650-4037-80bc-7b112bd4eac2");
  619. }
  620. @Test
  621. public void security_hotspot_type_excluded_by_default() {
  622. ComponentDto project = db.components().insertPublicProject();
  623. ComponentDto file = db.components().insertComponent(newFileDto(project));
  624. RuleDefinitionDto rule = db.rules().insert();
  625. db.issues().insert(rule, project, file, i -> i.setType(RuleType.BUG));
  626. db.issues().insert(rule, project, file, i -> i.setType(RuleType.VULNERABILITY));
  627. db.issues().insert(rule, project, file, i -> i.setType(RuleType.CODE_SMELL));
  628. db.issues().insert(rule, project, file, i -> i.setType(RuleType.SECURITY_HOTSPOT));
  629. indexPermissions();
  630. indexIssues();
  631. SearchWsResponse result = ws.newRequest().executeProtobuf(SearchWsResponse.class);
  632. assertThat(result.getIssuesList())
  633. .extracting(Issue::getType)
  634. .containsExactlyInAnyOrder(Common.RuleType.BUG, Common.RuleType.VULNERABILITY, Common.RuleType.CODE_SMELL);
  635. }
  636. @Test
  637. public void security_hotspot_type_included_when_explicitly_selected() {
  638. ComponentDto project = db.components().insertPublicProject();
  639. ComponentDto file = db.components().insertComponent(newFileDto(project));
  640. RuleDefinitionDto rule = newRule().getDefinition();
  641. db.issues().insert(rule, project, file, i -> i.setType(RuleType.BUG));
  642. db.issues().insert(rule, project, file, i -> i.setType(RuleType.VULNERABILITY));
  643. db.issues().insert(rule, project, file, i -> i.setType(RuleType.CODE_SMELL));
  644. db.issues().insert(rule, project, file, i -> i.setType(RuleType.SECURITY_HOTSPOT));
  645. indexPermissions();
  646. indexIssues();
  647. assertThat(ws.newRequest()
  648. .setParam("types", RuleType.SECURITY_HOTSPOT.toString())
  649. .executeProtobuf(SearchWsResponse.class).getIssuesList())
  650. .extracting(Issue::getType)
  651. .containsExactlyInAnyOrder(Common.RuleType.SECURITY_HOTSPOT);
  652. assertThat(ws.newRequest()
  653. .setParam("types", String.format("%s,%s", RuleType.BUG, RuleType.SECURITY_HOTSPOT))
  654. .executeProtobuf(SearchWsResponse.class).getIssuesList())
  655. .extracting(Issue::getType)
  656. .containsExactlyInAnyOrder(Common.RuleType.BUG, Common.RuleType.SECURITY_HOTSPOT);
  657. }
  658. @Test
  659. public void return_total_effort() {
  660. UserDto john = db.users().insertUser();
  661. userSession.logIn(john);
  662. RuleDefinitionDto rule = db.rules().insert();
  663. ComponentDto project = db.components().insertPublicProject();
  664. ComponentDto file = db.components().insertComponent(newFileDto(project));
  665. IssueDto issue1 = db.issues().insert(rule, project, file, i -> i.setEffort(10L));
  666. IssueDto issue2 = db.issues().insert(rule, project, file, i -> i.setEffort(15L));
  667. indexPermissions();
  668. indexIssues();
  669. SearchWsResponse response = ws.newRequest().executeProtobuf(SearchWsResponse.class);
  670. assertThat(response.getEffortTotal()).isEqualTo(25L);
  671. }
  672. @Test
  673. public void paging() {
  674. RuleDto rule = newRule();
  675. OrganizationDto organization = db.organizations().insert(o -> o.setKey("my-org-1"));
  676. ComponentDto project = db.components().insertComponent(ComponentTesting.newPublicProjectDto(organization, "PROJECT_ID").setDbKey("PROJECT_KEY"));
  677. indexPermissions();
  678. ComponentDto file = db.components().insertComponent(newFileDto(project, null, "FILE_ID").setDbKey("FILE_KEY"));
  679. for (int i = 0; i < 12; i++) {
  680. IssueDto issue = newDto(rule, file, project);
  681. dbClient.issueDao().insert(session, issue);
  682. }
  683. session.commit();
  684. indexIssues();
  685. ws.newRequest()
  686. .setParam(WebService.Param.PAGE, "2")
  687. .setParam(WebService.Param.PAGE_SIZE, "9")
  688. .execute()
  689. .assertJson(this.getClass(), "paging.json");
  690. }
  691. @Test
  692. public void paging_with_page_size_to_minus_one() {
  693. RuleDto rule = newRule();
  694. OrganizationDto organization = db.organizations().insert(o -> o.setKey("my-org-1"));
  695. ComponentDto project = db.components().insertComponent(ComponentTesting.newPublicProjectDto(organization, "PROJECT_ID").setDbKey("PROJECT_KEY"));
  696. indexPermissions();
  697. ComponentDto file = db.components().insertComponent(newFileDto(project, null, "FILE_ID").setDbKey("FILE_KEY"));
  698. for (int i = 0; i < 12; i++) {
  699. IssueDto issue = newDto(rule, file, project);
  700. dbClient.issueDao().insert(session, issue);
  701. }
  702. session.commit();
  703. indexIssues();
  704. ws.newRequest()
  705. .setParam(WebService.Param.PAGE, "1")
  706. .setParam(WebService.Param.PAGE_SIZE, "-1")
  707. .execute()
  708. .assertJson(this.getClass(), "paging_with_page_size_to_minus_one.json");
  709. }
  710. @Test
  711. public void deprecated_paging() {
  712. RuleDto rule = newRule();
  713. OrganizationDto organization = db.organizations().insert(o -> o.setKey("my-org-1"));
  714. ComponentDto project = db.components().insertComponent(ComponentTesting.newPublicProjectDto(organization, "PROJECT_ID").setDbKey("PROJECT_KEY"));
  715. indexPermissions();
  716. ComponentDto file = db.components().insertComponent(newFileDto(project, null, "FILE_ID").setDbKey("FILE_KEY"));
  717. for (int i = 0; i < 12; i++) {
  718. IssueDto issue = newDto(rule, file, project).setAssigneeUuid(null);
  719. dbClient.issueDao().insert(session, issue);
  720. }
  721. session.commit();
  722. indexIssues();
  723. ws.newRequest()
  724. .setParam(PARAM_PAGE_INDEX, "2")
  725. .setParam(PARAM_PAGE_SIZE, "9")
  726. .execute()
  727. .assertJson(this.getClass(), "deprecated_paging.json");
  728. }
  729. @Test
  730. public void default_page_size_is_100() {
  731. ws.newRequest()
  732. .execute()
  733. .assertJson(this.getClass(), "default_page_size_is_100.json");
  734. }
  735. // SONAR-10217
  736. @Test
  737. public void empty_search_with_unknown_branch() {
  738. SearchWsResponse response = ws.newRequest()
  739. .setParam("onComponentOnly", "true")
  740. .setParam("componentKeys", "foo")
  741. .setParam("branch", "bar")
  742. .executeProtobuf(SearchWsResponse.class);
  743. assertThat(response)
  744. .extracting(SearchWsResponse::getIssuesList, r -> r.getPaging().getTotal())
  745. .containsExactlyInAnyOrder(Collections.emptyList(), 0);
  746. }
  747. @Test
  748. public void empty_search() {
  749. SearchWsResponse response = ws.newRequest().executeProtobuf(SearchWsResponse.class);
  750. assertThat(response)
  751. .extracting(SearchWsResponse::getIssuesList, r -> r.getPaging().getTotal())
  752. .containsExactlyInAnyOrder(Collections.emptyList(), 0);
  753. }
  754. @Test
  755. public void fail_when_invalid_format() {
  756. expectedException.expect(IllegalArgumentException.class);
  757. expectedException.expectMessage("Date 'wrong-date-input' cannot be parsed as either a date or date+time");
  758. ws.newRequest()
  759. .setParam(PARAM_CREATED_AFTER, "wrong-date-input")
  760. .execute();
  761. }
  762. @Test
  763. public void test_definition() {
  764. WebService.Action def = ws.getDef();
  765. assertThat(def.key()).isEqualTo("search");
  766. assertThat(def.isInternal()).isFalse();
  767. assertThat(def.isPost()).isFalse();
  768. assertThat(def.since()).isEqualTo("3.6");
  769. assertThat(def.responseExampleAsString()).isNotEmpty();
  770. assertThat(def.params()).extracting("key").containsExactlyInAnyOrder(
  771. "additionalFields", "asc", "assigned", "assignees", "authors", "author", "componentKeys", "componentUuids", "branch",
  772. "pullRequest", "organization",
  773. "createdAfter", "createdAt", "createdBefore", "createdInLast", "directories", "facetMode", "facets", "fileUuids", "issues", "languages", "moduleUuids", "onComponentOnly",
  774. "p", "projects", "ps", "resolutions", "resolved", "rules", "s", "severities", "sinceLeakPeriod",
  775. "statuses", "tags", "types", "owaspTop10", "sansTop25", "cwe");
  776. assertThat(def.param("organization"))
  777. .matches(WebService.Param::isInternal)
  778. .matches(p -> p.since().equals("6.4"));
  779. WebService.Param branch = def.param(PARAM_BRANCH);
  780. assertThat(branch.isInternal()).isTrue();
  781. assertThat(branch.isRequired()).isFalse();
  782. assertThat(branch.since()).isEqualTo("6.6");
  783. WebService.Param projectUuids = def.param("projects");
  784. assertThat(projectUuids.description()).isEqualTo("To retrieve issues associated to a specific list of projects (comma-separated list of project keys). " +
  785. "This parameter is mostly used by the Issues page, please prefer usage of the componentKeys parameter. If this parameter is set, projectUuids must not be set.");
  786. }
  787. private RuleDto newRule() {
  788. RuleDto rule = RuleTesting.newXooX1()
  789. .setName("Rule name")
  790. .setDescription("Rule desc")
  791. .setStatus(RuleStatus.READY);
  792. db.rules().insert(rule.getDefinition());
  793. return rule;
  794. }
  795. private void indexPermissions() {
  796. permissionIndexer.indexOnStartup(permissionIndexer.getIndexTypes());
  797. }
  798. private void indexIssues() {
  799. issueIndexer.indexOnStartup(issueIndexer.getIndexTypes());
  800. }
  801. private void grantPermissionToAnyone(ComponentDto project, String permission) {
  802. dbClient.groupPermissionDao().insert(session,
  803. new GroupPermissionDto()
  804. .setOrganizationUuid(project.getOrganizationUuid())
  805. .setGroupId(null)
  806. .setResourceId(project.getId())
  807. .setRole(permission));
  808. session.commit();
  809. userSession.logIn().addProjectPermission(permission, project);
  810. }
  811. }