From 6cf79bf5c6b6e34ee943750c917351a1499dd386 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Pfeuffer?= Date: Mon, 11 Mar 2019 14:56:59 +0100 Subject: [PATCH 1/5] Disable default branch config without permission --- .../src/main/js/RepositoryConfig.js | 17 ++++++++++------- .../ui-components/src/BranchSelector.js | 4 +++- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/scm-plugins/scm-git-plugin/src/main/js/RepositoryConfig.js b/scm-plugins/scm-git-plugin/src/main/js/RepositoryConfig.js index aadb58eed6..062fab4752 100644 --- a/scm-plugins/scm-git-plugin/src/main/js/RepositoryConfig.js +++ b/scm-plugins/scm-git-plugin/src/main/js/RepositoryConfig.js @@ -18,7 +18,8 @@ type State = { error?: Error, branches: Branch[], selectedBranchName?: string, - defaultBranchChanged: boolean + defaultBranchChanged: boolean, + disabled: boolean }; const GIT_CONFIG_CONTENT_TYPE = "application/vnd.scmm-gitConfig+json"; @@ -33,7 +34,8 @@ class RepositoryConfig extends React.Component { loadingDefaultBranch: true, submitPending: false, branches: [], - defaultBranchChanged: false + defaultBranchChanged: false, + disabled: true }; } @@ -53,11 +55,11 @@ class RepositoryConfig extends React.Component { apiClient .get(repository._links.configuration.href) .then(response => response.json()) - .then(payload => payload.defaultBranch) - .then(selectedBranchName => + .then(payload => this.setState({ ...this.state, - selectedBranchName, + selectedBranchName: payload.defaultBranch, + disabled: !payload._links.update, loadingDefaultBranch: false }) ) @@ -98,7 +100,7 @@ class RepositoryConfig extends React.Component { render() { const { t } = this.props; - const { loadingBranches, loadingDefaultBranch, submitPending, error } = this.state; + const { loadingBranches, loadingDefaultBranch, submitPending, error, disabled } = this.state; if (error) { return ( @@ -121,11 +123,12 @@ class RepositoryConfig extends React.Component { branches={this.state.branches} selected={this.branchSelected} selectedBranch={this.state.selectedBranchName} + disabled={disabled} />
diff --git a/scm-ui-components/packages/ui-components/src/BranchSelector.js b/scm-ui-components/packages/ui-components/src/BranchSelector.js index c473527472..a9ba12cc7e 100644 --- a/scm-ui-components/packages/ui-components/src/BranchSelector.js +++ b/scm-ui-components/packages/ui-components/src/BranchSelector.js @@ -26,6 +26,7 @@ type Props = { selected: (branch?: Branch) => void, selectedBranch?: string, label: string, + disabled?: boolean, // context props classes: Object @@ -47,7 +48,7 @@ class BranchSelector extends React.Component { } render() { - const { branches, classes, label } = this.props; + const { branches, classes, label, disabled } = this.props; if (branches) { return ( @@ -79,6 +80,7 @@ class BranchSelector extends React.Component { className="is-fullwidth" options={branches.map(b => b.name)} optionSelected={this.branchSelected} + disabled={!!disabled} preselectedOption={ this.state.selectedBranch ? this.state.selectedBranch.name From 83baac3b188c3fe11365389519029d0bef1d1792 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Pfeuffer?= Date: Mon, 11 Mar 2019 15:05:31 +0100 Subject: [PATCH 2/5] Check permissions for git repository configuration --- .../scm/api/v2/resources/GitRepositoryConfigResource.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/api/v2/resources/GitRepositoryConfigResource.java b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/api/v2/resources/GitRepositoryConfigResource.java index 7b226186e5..292a934ea0 100644 --- a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/api/v2/resources/GitRepositoryConfigResource.java +++ b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/api/v2/resources/GitRepositoryConfigResource.java @@ -8,6 +8,7 @@ import sonia.scm.repository.GitRepositoryConfig; import sonia.scm.repository.NamespaceAndName; import sonia.scm.repository.Repository; import sonia.scm.repository.RepositoryManager; +import sonia.scm.repository.RepositoryPermissions; import sonia.scm.store.ConfigurationStore; import sonia.scm.web.GitVndMediaType; @@ -50,6 +51,7 @@ public class GitRepositoryConfigResource { }) public Response getRepositoryConfig(@PathParam("namespace") String namespace, @PathParam("name") String name) { Repository repository = getRepository(namespace, name); + RepositoryPermissions.read(repository).check(); ConfigurationStore repositoryConfigStore = getStore(repository); GitRepositoryConfig config = repositoryConfigStore.get(); GitRepositoryConfigDto dto = repositoryConfigMapper.map(config, repository); @@ -68,6 +70,7 @@ public class GitRepositoryConfigResource { }) public Response setRepositoryConfig(@PathParam("namespace") String namespace, @PathParam("name") String name, GitRepositoryConfigDto dto) { Repository repository = getRepository(namespace, name); + RepositoryPermissions.modify(repository).check(); ConfigurationStore repositoryConfigStore = getStore(repository); GitRepositoryConfig config = repositoryConfigMapper.map(dto); repositoryConfigStore.set(config); From d82f38e0f9373a4b8c779e06972576e39425c33f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Pfeuffer?= Date: Mon, 11 Mar 2019 16:00:16 +0100 Subject: [PATCH 3/5] Fix unit test --- .../sonia/scm/api/v2/resources/GitConfigResourceTest.java | 4 ++-- .../src/test/resources/sonia/scm/configuration/shiro.ini | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/api/v2/resources/GitConfigResourceTest.java b/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/api/v2/resources/GitConfigResourceTest.java index 8e657b1050..c25b5c5b60 100644 --- a/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/api/v2/resources/GitConfigResourceTest.java +++ b/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/api/v2/resources/GitConfigResourceTest.java @@ -159,7 +159,7 @@ public class GitConfigResourceTest { } @Test - @SubjectAware(username = "writeOnly") + @SubjectAware(username = "readWrite") public void shouldReadDefaultRepositoryConfig() throws URISyntaxException, UnsupportedEncodingException { when(repositoryManager.get(new NamespaceAndName("space", "X"))).thenReturn(new Repository("id", "git", "space", "X")); @@ -193,7 +193,7 @@ public class GitConfigResourceTest { } @Test - @SubjectAware(username = "writeOnly") + @SubjectAware(username = "readOnly") public void shouldReadStoredRepositoryConfig() throws URISyntaxException, UnsupportedEncodingException { when(repositoryManager.get(new NamespaceAndName("space", "X"))).thenReturn(new Repository("id", "git", "space", "X")); GitRepositoryConfig gitRepositoryConfig = new GitRepositoryConfig(); diff --git a/scm-plugins/scm-git-plugin/src/test/resources/sonia/scm/configuration/shiro.ini b/scm-plugins/scm-git-plugin/src/test/resources/sonia/scm/configuration/shiro.ini index 8a8ff98c2f..f0ffbe4ac5 100644 --- a/scm-plugins/scm-git-plugin/src/test/resources/sonia/scm/configuration/shiro.ini +++ b/scm-plugins/scm-git-plugin/src/test/resources/sonia/scm/configuration/shiro.ini @@ -7,7 +7,7 @@ admin = secret, admin [roles] reader = configuration:read:git writer = configuration:write:git -readerWriter = configuration:*:git +readerWriter = configuration:*:git,repository:*:id admin = * repoRead = repository:read:* repoWrite = repository:modify:* From 960780946b4bddf13c1af79564f9c37f58108651 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Pfeuffer?= Date: Thu, 14 Mar 2019 11:14:09 +0100 Subject: [PATCH 4/5] Fix repo config for user without permission Disable fields and remove submit buttons when user has not permission, aka no config links. --- .../src/main/js/RepositoryConfig.js | 12 +++++---- .../ui-components/src/forms/Textarea.js | 6 +++-- .../repos/components/form/RepositoryForm.js | 25 ++++++++++++++----- 3 files changed, 30 insertions(+), 13 deletions(-) diff --git a/scm-plugins/scm-git-plugin/src/main/js/RepositoryConfig.js b/scm-plugins/scm-git-plugin/src/main/js/RepositoryConfig.js index 062fab4752..fabb677045 100644 --- a/scm-plugins/scm-git-plugin/src/main/js/RepositoryConfig.js +++ b/scm-plugins/scm-git-plugin/src/main/js/RepositoryConfig.js @@ -112,6 +112,12 @@ class RepositoryConfig extends React.Component { ); } + const submitButton = disabled? null: ; + if (!(loadingBranches || loadingDefaultBranch)) { return ( <> @@ -125,11 +131,7 @@ class RepositoryConfig extends React.Component { selectedBranch={this.state.selectedBranchName} disabled={disabled} /> - + { submitButton }
diff --git a/scm-ui-components/packages/ui-components/src/forms/Textarea.js b/scm-ui-components/packages/ui-components/src/forms/Textarea.js index 4ea3741a31..d6f2cfcb05 100644 --- a/scm-ui-components/packages/ui-components/src/forms/Textarea.js +++ b/scm-ui-components/packages/ui-components/src/forms/Textarea.js @@ -14,7 +14,8 @@ type Props = { value?: string, autofocus?: boolean, onChange: (value: string, name?: string) => void, - helpText?: string + helpText?: string, + disabled?: boolean }; class Textarea extends React.Component { @@ -31,7 +32,7 @@ class Textarea extends React.Component { }; render() { - const { placeholder, value, label, helpText } = this.props; + const { placeholder, value, label, helpText, disabled } = this.props; return (
@@ -45,6 +46,7 @@ class Textarea extends React.Component { placeholder={placeholder} onChange={this.handleInput} value={value} + disabled={!!disabled} />
diff --git a/scm-ui/src/repos/components/form/RepositoryForm.js b/scm-ui/src/repos/components/form/RepositoryForm.js index a1cdf5a863..14121bee36 100644 --- a/scm-ui/src/repos/components/form/RepositoryForm.js +++ b/scm-ui/src/repos/components/form/RepositoryForm.js @@ -71,7 +71,8 @@ class RepositoryForm extends React.Component { this.state.nameValidationError || this.state.contactValidationError || this.isFalsy(repository.name) || - (namespaceStrategy === CUSTOM_NAMESPACE_STRATEGY && this.isFalsy(repository.namespace)) + (namespaceStrategy === CUSTOM_NAMESPACE_STRATEGY && + this.isFalsy(repository.namespace)) ); }; @@ -86,10 +87,24 @@ class RepositoryForm extends React.Component { return !this.props.repository; }; + isModifiable = () => { + return !!this.props.repository && !!this.props.repository._links.update; + }; + render() { const { loading, t } = this.props; const repository = this.state.repository; + const disabled = !this.isModifiable() && !this.isCreateMode(); + + const submitButton = disabled ? null : ( + + ); + let subtitle = null; if (this.props.repository) { // edit existing repo @@ -108,6 +123,7 @@ class RepositoryForm extends React.Component { validationError={this.state.contactValidationError} errorMessage={t("validation.contact-invalid")} helpText={t("help.contactHelpText")} + disabled={disabled} />