aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorssjenka <ssjenka@ops-slave-centos7-1.internal.sonarsource.com>2017-02-21 08:01:49 +0100
committerssjenka <ssjenka@ops-slave-centos7-1.internal.sonarsource.com>2017-02-21 08:01:49 +0100
commit7ce73daef17c282256aebc4513bbf5718e0b351d (patch)
tree2a96f079c1ceab0d3ece1f429c28f0386052d4a8
parent6c8d575311a638cd6ca565feff991db0f8c86bdb (diff)
parent5f09ded3a60950b1db7714f70f66850216acbff9 (diff)
downloadsonarqube-7ce73daef17c282256aebc4513bbf5718e0b351d.tar.gz
sonarqube-7ce73daef17c282256aebc4513bbf5718e0b351d.zip
Automatic merge from branch-6.3
* origin/branch-6.3: SONAR-8658 display "Apply Template" button for org admin SONAR-8658 add field configuration.canApplyPermissionTemplate to response of api/navigation/component change wording in organization form return `isDefault` in /api/navigation/organization SONAR-8658 fix applying of permission template fix ui glitch on settings page on safari
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/ui/ws/ComponentAction.java29
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/ui/ws/OrganizationAction.java6
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/ui/ws/ComponentActionTest.java18
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/ui/ws/OrganizationActionTest.java5
-rw-r--r--server/sonar-web/src/main/js/apps/account/organizations/CreateOrganizationForm.js2
-rw-r--r--server/sonar-web/src/main/js/apps/permissions/project/components/PageHeader.js9
-rw-r--r--server/sonar-web/src/main/js/apps/settings/styles.css2
-rw-r--r--sonar-core/src/main/resources/org/sonar/l10n/core.properties4
8 files changed, 54 insertions, 21 deletions
diff --git a/server/sonar-server/src/main/java/org/sonar/server/ui/ws/ComponentAction.java b/server/sonar-server/src/main/java/org/sonar/server/ui/ws/ComponentAction.java
index fa72601e834..dd8839b82d5 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/ui/ws/ComponentAction.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/ui/ws/ComponentAction.java
@@ -61,6 +61,7 @@ import static org.sonar.api.web.UserRole.ADMIN;
import static org.sonar.api.web.UserRole.USER;
import static org.sonar.core.permission.GlobalPermissions.QUALITY_GATE_ADMIN;
import static org.sonar.core.permission.GlobalPermissions.QUALITY_PROFILE_ADMIN;
+import static org.sonar.core.permission.GlobalPermissions.SYSTEM_ADMIN;
import static org.sonar.server.user.AbstractUserSession.insufficientPrivilegesException;
import static org.sonar.server.ws.KeyExamples.KEY_PROJECT_EXAMPLE_001;
@@ -211,12 +212,12 @@ public class ComponentAction implements NavigationWsAction {
}
private void writeConfiguration(JsonWriter json, ComponentDto component) {
- boolean isAdmin = userSession.hasComponentPermission(ADMIN, component);
+ boolean isProjectAdmin = userSession.hasComponentPermission(ADMIN, component);
json.name("configuration").beginObject();
- writeConfigPageAccess(json, isAdmin, component);
+ writeConfigPageAccess(json, isProjectAdmin, component);
- if (isAdmin) {
+ if (isProjectAdmin) {
json.name("extensions").beginArray();
List<Page> configPages = pageRepository.getComponentPages(true, component.qualifier());
configPages.forEach(page -> writePage(json, page));
@@ -225,21 +226,23 @@ public class ComponentAction implements NavigationWsAction {
json.endObject();
}
- private void writeConfigPageAccess(JsonWriter json, boolean isAdmin, ComponentDto component) {
+ private void writeConfigPageAccess(JsonWriter json, boolean isProjectAdmin, ComponentDto component) {
boolean isProject = Qualifiers.PROJECT.equals(component.qualifier());
- boolean showManualMeasures = isAdmin && !Qualifiers.DIRECTORY.equals(component.qualifier());
+ boolean showManualMeasures = isProjectAdmin && !Qualifiers.DIRECTORY.equals(component.qualifier());
boolean isQualityProfileAdmin = userSession.hasOrganizationPermission(component.getOrganizationUuid(), QUALITY_PROFILE_ADMIN);
boolean isQualityGateAdmin = userSession.hasOrganizationPermission(component.getOrganizationUuid(), QUALITY_GATE_ADMIN);
+ boolean isOrganizationAdmin = userSession.hasOrganizationPermission(component.getOrganizationUuid(), SYSTEM_ADMIN);
- json.prop("showSettings", isAdmin && componentTypeHasProperty(component, PROPERTY_CONFIGURABLE));
- json.prop("showQualityProfiles", isProject && (isAdmin || isQualityProfileAdmin));
- json.prop("showQualityGates", isProject && (isAdmin || isQualityGateAdmin));
+ json.prop("showSettings", isProjectAdmin && componentTypeHasProperty(component, PROPERTY_CONFIGURABLE));
+ json.prop("showQualityProfiles", isProject && (isProjectAdmin || isQualityProfileAdmin));
+ json.prop("showQualityGates", isProject && (isProjectAdmin || isQualityGateAdmin));
json.prop("showManualMeasures", showManualMeasures);
- json.prop("showLinks", isAdmin && isProject);
- json.prop("showPermissions", isAdmin && componentTypeHasProperty(component, PROPERTY_HAS_ROLE_POLICY));
- json.prop("showHistory", isAdmin && componentTypeHasProperty(component, PROPERTY_MODIFIABLE_HISTORY));
- json.prop("showUpdateKey", isAdmin && componentTypeHasProperty(component, PROPERTY_UPDATABLE_KEY));
- json.prop("showBackgroundTasks", isAdmin);
+ json.prop("showLinks", isProjectAdmin && isProject);
+ json.prop("showPermissions", isProjectAdmin && componentTypeHasProperty(component, PROPERTY_HAS_ROLE_POLICY));
+ json.prop("showHistory", isProjectAdmin && componentTypeHasProperty(component, PROPERTY_MODIFIABLE_HISTORY));
+ json.prop("showUpdateKey", isProjectAdmin && componentTypeHasProperty(component, PROPERTY_UPDATABLE_KEY));
+ json.prop("showBackgroundTasks", isProjectAdmin);
+ json.prop("canApplyPermissionTemplate", isOrganizationAdmin);
}
private boolean componentTypeHasProperty(ComponentDto component, String resourceTypeProperty) {
diff --git a/server/sonar-server/src/main/java/org/sonar/server/ui/ws/OrganizationAction.java b/server/sonar-server/src/main/java/org/sonar/server/ui/ws/OrganizationAction.java
index 47cc9146e5c..2b66b7b9eb3 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/ui/ws/OrganizationAction.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/ui/ws/OrganizationAction.java
@@ -27,6 +27,7 @@ import org.sonar.core.permission.GlobalPermissions;
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.server.user.UserSession;
import static org.sonar.core.permission.GlobalPermissions.SYSTEM_ADMIN;
@@ -38,10 +39,12 @@ public class OrganizationAction implements NavigationWsAction {
private static final String PARAM_ORGANIZATION = "organization";
private final DbClient dbClient;
+ private final DefaultOrganizationProvider defaultOrganizationProvider;
private final UserSession userSession;
- public OrganizationAction(DbClient dbClient, UserSession userSession) {
+ public OrganizationAction(DbClient dbClient, DefaultOrganizationProvider defaultOrganizationProvider, UserSession userSession) {
this.dbClient = dbClient;
+ this.defaultOrganizationProvider = defaultOrganizationProvider;
this.userSession = userSession;
}
@@ -83,6 +86,7 @@ public class OrganizationAction implements NavigationWsAction {
.prop("canAdmin", userSession.hasOrganizationPermission(organizationUuid, SYSTEM_ADMIN))
.prop("canProvisionProjects", userSession.hasOrganizationPermission(organizationUuid, GlobalPermissions.PROVISIONING))
.prop("canDelete", organization.isGuarded() ? userSession.isSystemAdministrator() : userSession.hasOrganizationPermission(organizationUuid, SYSTEM_ADMIN))
+ .prop("isDefault", organization.getKey().equals(defaultOrganizationProvider.get().getKey()))
.endObject();
}
}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/ui/ws/ComponentActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/ui/ws/ComponentActionTest.java
index 38baa6485f7..0a293bc8974 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/ui/ws/ComponentActionTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/ui/ws/ComponentActionTest.java
@@ -35,6 +35,7 @@ import org.sonar.api.web.page.Page;
import org.sonar.api.web.page.Page.Qualifier;
import org.sonar.api.web.page.PageDefinition;
import org.sonar.core.component.DefaultResourceTypes;
+import org.sonar.core.permission.GlobalPermissions;
import org.sonar.core.platform.PluginRepository;
import org.sonar.db.DbClient;
import org.sonar.db.DbTester;
@@ -380,6 +381,23 @@ public class ComponentActionTest {
assertJson(result).ignoreFields("snapshotDate", "key", "qualityGate.key").isSimilarTo(ws.getDef().responseExampleAsString());
}
+ @Test
+ public void canApplyPermissionTemplate_is_true_if_logged_in_as_organization_administrator() {
+ init(createPages());
+ OrganizationDto org = dbTester.organizations().insert();
+ ComponentDto project = dbTester.components().insertProject(org);
+
+ userSessionRule.logIn()
+ .addProjectUuidPermissions(UserRole.ADMIN, project.uuid())
+ .addOrganizationPermission(org.getUuid(), GlobalPermissions.SYSTEM_ADMIN);
+ assertJson(execute(project.key())).isSimilarTo("{\"configuration\": {\"canApplyPermissionTemplate\": true}}");
+
+ userSessionRule.logIn()
+ .addProjectUuidPermissions(UserRole.ADMIN, project.uuid());
+
+ assertJson(execute(project.key())).isSimilarTo("{\"configuration\": {\"canApplyPermissionTemplate\": false}}");
+ }
+
private void init(Page... pages) {
PluginRepository pluginRepository = mock(PluginRepository.class);
when(pluginRepository.hasPlugin(anyString())).thenReturn(true);
diff --git a/server/sonar-server/src/test/java/org/sonar/server/ui/ws/OrganizationActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/ui/ws/OrganizationActionTest.java
index 47193174de5..46174db1ace 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/ui/ws/OrganizationActionTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/ui/ws/OrganizationActionTest.java
@@ -28,6 +28,8 @@ import org.sonar.api.utils.System2;
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.ws.TestRequest;
import org.sonar.server.ws.TestResponse;
@@ -46,8 +48,9 @@ public class OrganizationActionTest {
public ExpectedException expectedException = ExpectedException.none();
private DbClient dbClient = dbTester.getDbClient();
+ private DefaultOrganizationProvider defaultOrganizationProvider = TestDefaultOrganizationProvider.from(dbTester);
- private WsActionTester underTest = new WsActionTester(new OrganizationAction(dbClient, userSession));
+ private WsActionTester underTest = new WsActionTester(new OrganizationAction(dbClient, defaultOrganizationProvider, userSession));
@Test
public void verify_definition() {
diff --git a/server/sonar-web/src/main/js/apps/account/organizations/CreateOrganizationForm.js b/server/sonar-web/src/main/js/apps/account/organizations/CreateOrganizationForm.js
index d85e3413036..9a0c10de08c 100644
--- a/server/sonar-web/src/main/js/apps/account/organizations/CreateOrganizationForm.js
+++ b/server/sonar-web/src/main/js/apps/account/organizations/CreateOrganizationForm.js
@@ -136,6 +136,7 @@ class CreateOrganizationForm extends React.Component {
name="name"
required={true}
type="text"
+ minLength="2"
maxLength="64"
value={this.state.name}
disabled={this.state.loading}
@@ -151,6 +152,7 @@ class CreateOrganizationForm extends React.Component {
<input id="organization-key"
name="key"
type="text"
+ minLength="2"
maxLength="64"
value={this.state.key}
disabled={this.state.loading}
diff --git a/server/sonar-web/src/main/js/apps/permissions/project/components/PageHeader.js b/server/sonar-web/src/main/js/apps/permissions/project/components/PageHeader.js
index 77f48eb680c..bc97d1c6ddf 100644
--- a/server/sonar-web/src/main/js/apps/permissions/project/components/PageHeader.js
+++ b/server/sonar-web/src/main/js/apps/permissions/project/components/PageHeader.js
@@ -23,7 +23,6 @@ import { translate } from '../../../../helpers/l10n';
import ApplyTemplateView from '../views/ApplyTemplateView';
import { loadHolders } from '../store/actions';
import { isPermissionsAppLoading } from '../../../../store/rootReducer';
-import { isUserAdmin } from '../../../../helpers/users';
class PageHeader extends React.Component {
static propTypes = {
@@ -44,12 +43,16 @@ class PageHeader extends React.Component {
e.preventDefault();
e.target.blur();
const { project, loadHolders } = this.props;
- new ApplyTemplateView({ project })
+ const organization = project.organization ? { key: project.organization } : null;
+ new ApplyTemplateView({ project, organization })
.on('done', () => loadHolders(project.key))
.render();
}
render () {
+ const configuration = this.props.project.configuration;
+ const canApplyPermissionTemplate = configuration != null && configuration.canApplyPermissionTemplate;
+
return (
<header className="page-header">
<h1 className="page-title">
@@ -60,7 +63,7 @@ class PageHeader extends React.Component {
<i className="spinner"/>
)}
- {isUserAdmin(this.props.currentUser) && (
+ {canApplyPermissionTemplate && (
<div className="page-actions">
<button className="js-apply-template" onClick={this.handleApplyTemplate}>
Apply Template
diff --git a/server/sonar-web/src/main/js/apps/settings/styles.css b/server/sonar-web/src/main/js/apps/settings/styles.css
index 230724470cc..4a2926f69db 100644
--- a/server/sonar-web/src/main/js/apps/settings/styles.css
+++ b/server/sonar-web/src/main/js/apps/settings/styles.css
@@ -115,7 +115,7 @@
right: 0;
height: 30px;
display: block;
- background: linear-gradient(to bottom, transparent, #fff);
+ background: linear-gradient(to bottom, rgba(255, 255, 255, 0), rgb(255, 255, 255));
content: "";
}
diff --git a/sonar-core/src/main/resources/org/sonar/l10n/core.properties b/sonar-core/src/main/resources/org/sonar/l10n/core.properties
index 56479a79be1..108206c6bce 100644
--- a/sonar-core/src/main/resources/org/sonar/l10n/core.properties
+++ b/sonar-core/src/main/resources/org/sonar/l10n/core.properties
@@ -2773,7 +2773,7 @@ organization.delete.description=Delete this organization from SonarQube. All pro
organization.delete.question=Are you sure you want to delete this organization?
organization.deleted=Organization has been deleted.
organization.description=Description
-organization.description.description=Description of the organization (256 characters max).
+organization.description.description=Description of the organization.
organization.edit=Edit Organization
organization.key=Key
organization.key.description=Key of the organization (2 to 32 characters). All chars must be lower-case letters (a to z), digits or dash (but dash can neither be trailing nor heading). When not specified, the key is computed from the name.
@@ -2781,4 +2781,4 @@ organization.name=Name
organization.name.description=Name of the organization (2 to 64 characters).
organization.updated=Organization details have been updated.
organization.url=Url
-organization.url.description=Url of the homepage of the organization (256 characters max).
+organization.url.description=Url of the homepage of the organization.