*/
package org.sonar.server.ui.ws;
+import java.util.List;
+import java.util.function.Consumer;
import org.sonar.api.server.ws.Request;
import org.sonar.api.server.ws.Response;
import org.sonar.api.server.ws.WebService;
import org.sonar.api.utils.text.JsonWriter;
+import org.sonar.api.web.page.Page;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
import org.sonar.db.organization.OrganizationDto;
-import org.sonar.server.organization.DefaultOrganizationProvider;
import org.sonar.db.permission.OrganizationPermission;
+import org.sonar.server.organization.DefaultOrganizationProvider;
+import org.sonar.server.ui.PageRepository;
import org.sonar.server.user.UserSession;
+import static org.sonar.server.ws.KeyExamples.KEY_ORG_EXAMPLE_001;
import static org.sonar.server.ws.WsUtils.checkFoundWithOptional;
public class OrganizationAction implements NavigationWsAction {
private final DbClient dbClient;
private final DefaultOrganizationProvider defaultOrganizationProvider;
private final UserSession userSession;
+ private final PageRepository pageRepository;
- public OrganizationAction(DbClient dbClient, DefaultOrganizationProvider defaultOrganizationProvider, UserSession userSession) {
+ public OrganizationAction(DbClient dbClient, DefaultOrganizationProvider defaultOrganizationProvider, UserSession userSession, PageRepository pageRepository) {
this.dbClient = dbClient;
this.defaultOrganizationProvider = defaultOrganizationProvider;
this.userSession = userSession;
+ this.pageRepository = pageRepository;
}
@Override
projectNavigation.createParam(PARAM_ORGANIZATION)
.setRequired(true)
.setDescription("the organization key")
- .setExampleValue("my-org");
+ .setExampleValue(KEY_ORG_EXAMPLE_001);
}
@Override
.prop("canAdmin", userSession.hasPermission(OrganizationPermission.ADMINISTER, organization))
.prop("canProvisionProjects", userSession.hasPermission(OrganizationPermission.PROVISION_PROJECTS, organization))
.prop("canDelete", organization.isGuarded() ? userSession.isSystemAdministrator() : userSession.hasPermission(OrganizationPermission.ADMINISTER, organization))
- .prop("isDefault", organization.getKey().equals(defaultOrganizationProvider.get().getKey()))
- .endObject();
+ .prop("isDefault", organization.getKey().equals(defaultOrganizationProvider.get().getKey()));
+ List<Page> pages = pageRepository.getOrganizationPages(false);
+ json.name("pages");
+ writePages(json, pages);
+ if (userSession.hasPermission(OrganizationPermission.ADMINISTER, organization)) {
+ List<Page> adminPages = pageRepository.getOrganizationPages(true);
+ json.name("adminPages");
+ writePages(json, adminPages);
+ }
+ json.endObject();
+ }
+
+ private static void writePages(JsonWriter json, List<Page> pages) {
+ json.beginArray();
+ pages.forEach(writePage(json));
+ json.endArray();
+ }
+ private static Consumer<Page> writePage(JsonWriter json) {
+ return page -> json.beginObject()
+ .prop("key", page.getKey())
+ .prop("name", page.getName())
+ .endObject();
}
}
import org.junit.rules.ExpectedException;
import org.sonar.api.server.ws.WebService;
import org.sonar.api.utils.System2;
+import org.sonar.api.web.page.Page;
+import org.sonar.api.web.page.PageDefinition;
+import org.sonar.core.platform.PluginRepository;
import org.sonar.db.DbClient;
import org.sonar.db.DbTester;
import org.sonar.db.organization.OrganizationDto;
import org.sonar.server.organization.DefaultOrganizationProvider;
import org.sonar.server.organization.TestDefaultOrganizationProvider;
import org.sonar.server.tester.UserSessionRule;
+import org.sonar.server.ui.PageRepository;
import org.sonar.server.ws.TestRequest;
import org.sonar.server.ws.TestResponse;
import org.sonar.server.ws.WsActionTester;
import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+import static org.sonar.api.web.page.Page.Scope.ORGANIZATION;
import static org.sonar.db.permission.OrganizationPermission.ADMINISTER;
import static org.sonar.db.permission.OrganizationPermission.PROVISION_PROJECTS;
import static org.sonar.test.JsonAssert.assertJson;
private DbClient dbClient = dbTester.getDbClient();
private DefaultOrganizationProvider defaultOrganizationProvider = TestDefaultOrganizationProvider.from(dbTester);
+ private PageRepository pageRepository = mock(PageRepository.class);
- private WsActionTester underTest = new WsActionTester(new OrganizationAction(dbClient, defaultOrganizationProvider, userSession));
+ private WsActionTester ws = new WsActionTester(new OrganizationAction(dbClient, defaultOrganizationProvider, userSession, pageRepository));
@Test
public void verify_definition() {
- WebService.Action def = underTest.getDef();
+ WebService.Action def = ws.getDef();
assertThat(def.isInternal()).isTrue();
assertThat(def.description()).isEqualTo("Get information concerning organization navigation for the current user");
}
@Test
- public void verify_example() {
+ public void json_example() {
+ initWithPages(
+ Page.builder("my-plugin/org-page").setName("Organization page").setScope(ORGANIZATION).build(),
+ Page.builder("my-plugin/org-admin-page").setName("Organization admin page").setScope(ORGANIZATION).setAdmin(true).build()
+ );
OrganizationDto organization = dbTester.organizations().insert(dto -> dto.setGuarded(true));
userSession.logIn()
.addPermission(ADMINISTER, organization)
TestResponse response = executeRequest(organization);
assertJson(response.getInput())
- .isSimilarTo(underTest.getDef().responseExampleAsString());
+ .isSimilarTo(ws.getDef().responseExampleAsString());
+ }
+
+ @Test
+ public void filter_out_admin_pages_when_user_is_not_admin() {
+ initWithPages(
+ Page.builder("my-plugin/org-page").setName("Organization page").setScope(ORGANIZATION).build(),
+ Page.builder("my-plugin/org-admin-page").setName("Organization admin page").setScope(ORGANIZATION).setAdmin(true).build()
+ );
+ OrganizationDto organization = dbTester.organizations().insert(dto -> dto.setGuarded(true));
+ userSession.logIn()
+ .addPermission(PROVISION_PROJECTS, organization);
+
+ TestResponse response = executeRequest(organization);
+
+ assertThat(response.getInput())
+ .contains("my-plugin/org-page")
+ .doesNotContain("my-plugin/org-admin-page");
}
@Test
verifyResponse(executeRequest(org2), false, true, false);
}
+ private void initWithPages(Page... pages) {
+ PluginRepository pluginRepository = mock(PluginRepository.class);
+ when(pluginRepository.hasPlugin(anyString())).thenReturn(true);
+ PageRepository pageRepository = new PageRepository(pluginRepository, new PageDefinition[] {context -> {
+ for (Page page : pages) {
+ context.addPage(page);
+ }
+ }});
+ pageRepository.start();
+ ws = new WsActionTester(new OrganizationAction(dbClient, defaultOrganizationProvider, userSession, pageRepository));
+ }
+
private TestResponse executeRequest(@Nullable OrganizationDto organization) {
- TestRequest request = underTest.newRequest();
+ TestRequest request = ws.newRequest();
if (organization != null) {
request.setParam("organization", organization.getKey());
}
" \"canAdmin\": " + canAdmin + "," +
" \"canProvisionProjects\": " + canProvisionProjects + "," +
" \"canDelete\": " + canDelete +
+ " \"pages\": []" +
" }" +
"}");
}