mirror of
https://github.com/scm-manager/scm-manager.git
synced 2026-03-03 19:00:52 +01:00
Add namespace cli commands (#2093)
Adds the CLI commands that are available to handle repository permissions on repositories for namespaces. Co-authored-by: Eduard Heimbuch <eduard.heimbuch@cloudogu.com>
This commit is contained in:
@@ -1,2 +1,2 @@
|
||||
- type: added
|
||||
description: Cli commands to modify repository permissions ([#2090](https://github.com/scm-manager/scm-manager/pull/2090))
|
||||
description: Cli commands to modify repository and namespace permissions ([#2090](https://github.com/scm-manager/scm-manager/pull/2090) and [#2093](https://github.com/scm-manager/scm-manager/pull/2093))
|
||||
|
||||
@@ -46,7 +46,7 @@ import static java.util.Collections.unmodifiableCollection;
|
||||
)
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
@XmlRootElement(name = "namespaces")
|
||||
public class Namespace implements PermissionObject, Cloneable {
|
||||
public class Namespace implements PermissionObject, Cloneable, RepositoryPermissionHolder {
|
||||
|
||||
private String namespace;
|
||||
private Set<RepositoryPermission> permissions = new HashSet<>();
|
||||
|
||||
@@ -46,7 +46,6 @@ import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
@@ -65,7 +64,9 @@ import java.util.Set;
|
||||
@Guard(guard = RepositoryPermissionGuard.class)
|
||||
}
|
||||
)
|
||||
public class Repository extends BasicPropertiesAware implements ModelObject, PermissionObject, RepositoryCoordinates {
|
||||
public class Repository
|
||||
extends BasicPropertiesAware
|
||||
implements ModelObject, PermissionObject, RepositoryCoordinates, RepositoryPermissionHolder {
|
||||
|
||||
private static final long serialVersionUID = 3486560714961909711L;
|
||||
|
||||
@@ -210,28 +211,6 @@ public class Repository extends BasicPropertiesAware implements ModelObject, Per
|
||||
return Collections.unmodifiableCollection(permissions);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the permission for the given user, if present, or an empty {@link Optional} otherwise.
|
||||
*
|
||||
* @since 2.38.0
|
||||
*/
|
||||
public Optional<RepositoryPermission> findUserPermission(String userId) {
|
||||
return findPermission(userId, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the permission for the given group, if present, or an empty {@link Optional} otherwise.
|
||||
*
|
||||
* @since 2.38.0
|
||||
*/
|
||||
public Optional<RepositoryPermission> findGroupPermission(String groupId) {
|
||||
return findPermission(groupId, true);
|
||||
}
|
||||
|
||||
private Optional<RepositoryPermission> findPermission(String x, boolean isGroup) {
|
||||
return getPermissions().stream().filter(p -> p.isGroupPermission() == isGroup && p.getName().equals(x)).findFirst();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the type (hg, git, svn ...) of the {@link Repository}.
|
||||
*
|
||||
|
||||
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020-present Cloudogu GmbH and Contributors
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package sonia.scm.repository;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* This abstracts the permissions of {@link Repository} and {@link Namespace} objects.
|
||||
*/
|
||||
public interface RepositoryPermissionHolder {
|
||||
|
||||
/**
|
||||
* Returns a collection of all permissions for this object.
|
||||
*/
|
||||
Collection<RepositoryPermission> getPermissions();
|
||||
|
||||
/**
|
||||
* Sets and therefore overwrites the permissions for this object.
|
||||
*
|
||||
* @param permissions The new permissions for this object.
|
||||
*/
|
||||
void setPermissions(Collection<RepositoryPermission> permissions);
|
||||
|
||||
/**
|
||||
* Adds a single permission to the current set of permissions for this object.
|
||||
*
|
||||
* @param newPermission The new permission that will be added to the existing permissions.
|
||||
*/
|
||||
void addPermission(RepositoryPermission newPermission);
|
||||
|
||||
/**
|
||||
* Removes a single permission from the current set of permissions for this object.
|
||||
*
|
||||
* @param permission The permission that should be removed from the existing permissions.
|
||||
* @return <code>true</code>, if the given permission was part of the permissions for this object, <code>false</code>
|
||||
* otherwise.
|
||||
*/
|
||||
boolean removePermission(RepositoryPermission permission);
|
||||
|
||||
/**
|
||||
* Returns the permission for the given user, if present, or an empty {@link Optional} otherwise.
|
||||
*
|
||||
* @since 2.38.0
|
||||
*/
|
||||
default Optional<RepositoryPermission> findUserPermission(String userId) {
|
||||
return findPermission(userId, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the permission for the given group, if present, or an empty {@link Optional} otherwise.
|
||||
*
|
||||
* @since 2.38.0
|
||||
*/
|
||||
default Optional<RepositoryPermission> findGroupPermission(String groupId) {
|
||||
return findPermission(groupId, true);
|
||||
}
|
||||
|
||||
private Optional<RepositoryPermission> findPermission(String name, boolean isGroup) {
|
||||
return getPermissions().stream().filter(p -> p.isGroupPermission() == isGroup && p.getName().equals(name)).findFirst();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020-present Cloudogu GmbH and Contributors
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package sonia.scm.repository.cli;
|
||||
|
||||
import picocli.CommandLine;
|
||||
|
||||
@CommandLine.Command(name = "namespace")
|
||||
public class NamespaceCommand {}
|
||||
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020-present Cloudogu GmbH and Contributors
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package sonia.scm.repository.cli;
|
||||
|
||||
import picocli.CommandLine;
|
||||
import sonia.scm.cli.ParentCommand;
|
||||
import sonia.scm.cli.TemplateRenderer;
|
||||
import sonia.scm.repository.RepositoryManager;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import static java.util.Collections.emptyMap;
|
||||
|
||||
@ParentCommand(value = NamespaceCommand.class)
|
||||
@CommandLine.Command(name = "list", aliases = "ls")
|
||||
class NamespaceListCommand implements Runnable {
|
||||
|
||||
|
||||
@CommandLine.Mixin
|
||||
private final TemplateRenderer templateRenderer;
|
||||
private final RepositoryManager manager;
|
||||
|
||||
@Inject
|
||||
public NamespaceListCommand(RepositoryManager manager, TemplateRenderer templateRenderer, RepositoryToRepositoryCommandDtoMapper mapper) {
|
||||
this.manager = manager;
|
||||
this.templateRenderer = templateRenderer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
manager.getAllNamespaces()
|
||||
.forEach(this::render);
|
||||
}
|
||||
|
||||
private void render(String namespace) {
|
||||
templateRenderer.renderToStdout(namespace + "\n", emptyMap());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020-present Cloudogu GmbH and Contributors
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package sonia.scm.repository.cli;
|
||||
|
||||
import sonia.scm.repository.Namespace;
|
||||
import sonia.scm.repository.NamespaceManager;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import static java.util.Optional.empty;
|
||||
|
||||
class NamespacePermissionBaseAdapter implements PermissionBaseAdapter<Namespace> {
|
||||
|
||||
private final NamespaceManager namespaceManager;
|
||||
private final RepositoryTemplateRenderer templateRenderer;
|
||||
|
||||
NamespacePermissionBaseAdapter(NamespaceManager namespaceManager, RepositoryTemplateRenderer templateRenderer) {
|
||||
this.namespaceManager = namespaceManager;
|
||||
this.templateRenderer = templateRenderer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<Namespace> get(String namespace) {
|
||||
Optional<Namespace> ns = namespaceManager.get(namespace);
|
||||
if (ns.isPresent()) {
|
||||
return ns;
|
||||
} else {
|
||||
templateRenderer.renderNotFoundError();
|
||||
return empty();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void modify(Namespace namespace) {
|
||||
namespaceManager.modify(namespace);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020-present Cloudogu GmbH and Contributors
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package sonia.scm.repository.cli;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import picocli.CommandLine;
|
||||
import sonia.scm.cli.ParentCommand;
|
||||
import sonia.scm.cli.PermissionDescriptionResolver;
|
||||
import sonia.scm.repository.Namespace;
|
||||
import sonia.scm.repository.NamespaceManager;
|
||||
import sonia.scm.repository.RepositoryRoleManager;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
@CommandLine.Command(name = "add-permissions")
|
||||
@ParentCommand(value = NamespaceCommand.class)
|
||||
class NamespacePermissionsAddCommand extends PermissionsAddCommand<Namespace> implements Runnable {
|
||||
|
||||
@CommandLine.Parameters(paramLabel = "namespace", index = "0", descriptionKey = "scm.namespace.add-permissions.namespace")
|
||||
private String namespace;
|
||||
|
||||
@Inject
|
||||
NamespacePermissionsAddCommand(NamespaceManager namespaceManager, RepositoryRoleManager roleManager, PermissionDescriptionResolver permissionDescriptionResolver, RepositoryTemplateRenderer templateRenderer) {
|
||||
super(roleManager, permissionDescriptionResolver, templateRenderer, new NamespacePermissionBaseAdapter(namespaceManager, templateRenderer));
|
||||
}
|
||||
|
||||
@Override
|
||||
String getIdentifier() {
|
||||
return namespace;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void setNamespace(String namespace) {
|
||||
this.namespace = namespace;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020-present Cloudogu GmbH and Contributors
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package sonia.scm.repository.cli;
|
||||
|
||||
import picocli.CommandLine;
|
||||
import sonia.scm.cli.ParentCommand;
|
||||
import sonia.scm.cli.PermissionDescriptionResolver;
|
||||
import sonia.scm.repository.RepositoryRoleManager;
|
||||
import sonia.scm.security.RepositoryPermissionProvider;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
@CommandLine.Command(name = "available-permissions")
|
||||
@ParentCommand(value = NamespaceCommand.class)
|
||||
class NamespacePermissionsAvailableCommand extends PermissionsAvailableCommand {
|
||||
|
||||
@Inject
|
||||
public NamespacePermissionsAvailableCommand(RepositoryTemplateRenderer templateRenderer, RepositoryPermissionProvider repositoryPermissionProvider, PermissionDescriptionResolver permissionDescriptionResolver, RepositoryRoleManager repositoryRoleManager) {
|
||||
super(templateRenderer, repositoryPermissionProvider, permissionDescriptionResolver, repositoryRoleManager);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020-present Cloudogu GmbH and Contributors
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package sonia.scm.repository.cli;
|
||||
|
||||
import picocli.CommandLine;
|
||||
import sonia.scm.cli.ParentCommand;
|
||||
import sonia.scm.repository.Namespace;
|
||||
import sonia.scm.repository.NamespaceManager;
|
||||
import sonia.scm.repository.RepositoryRoleManager;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
@CommandLine.Command(name = "clear-permissions")
|
||||
@ParentCommand(value = NamespaceCommand.class)
|
||||
class NamespacePermissionsClearCommand extends PermissionClearCommand<Namespace> {
|
||||
|
||||
@CommandLine.Parameters(paramLabel = "namespace", index = "0", descriptionKey = "scm.namespace.clear-permissions.namespace")
|
||||
private String namespace;
|
||||
|
||||
@Inject
|
||||
public NamespacePermissionsClearCommand(NamespaceManager namespaceManager, RepositoryRoleManager roleManager, RepositoryTemplateRenderer templateRenderer) {
|
||||
super(roleManager, templateRenderer, new NamespacePermissionBaseAdapter(namespaceManager, templateRenderer));
|
||||
}
|
||||
|
||||
@Override
|
||||
String getIdentifier() {
|
||||
return namespace;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020-present Cloudogu GmbH and Contributors
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package sonia.scm.repository.cli;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import picocli.CommandLine;
|
||||
import sonia.scm.cli.CommandValidator;
|
||||
import sonia.scm.cli.ParentCommand;
|
||||
import sonia.scm.repository.Namespace;
|
||||
import sonia.scm.repository.NamespaceManager;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
@CommandLine.Command(name = "list-permissions")
|
||||
@ParentCommand(value = NamespaceCommand.class)
|
||||
class NamespacePermissionsListCommand extends PermissionsListCommand<Namespace> {
|
||||
|
||||
@CommandLine.Parameters(paramLabel = "namespace", index = "0", descriptionKey = "scm.namespace.list-permissions.namespace")
|
||||
private String namespace;
|
||||
|
||||
@Inject
|
||||
public NamespacePermissionsListCommand(RepositoryTemplateRenderer templateRenderer, CommandValidator validator, NamespaceManager manager, RepositoryPermissionBeanMapper beanMapper) {
|
||||
super(templateRenderer, validator, new NamespacePermissionBaseAdapter(manager, templateRenderer), beanMapper);
|
||||
}
|
||||
|
||||
@Override
|
||||
String getIdentifier() {
|
||||
return namespace;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void setNamespace(String namespace) {
|
||||
this.namespace = namespace;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020-present Cloudogu GmbH and Contributors
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package sonia.scm.repository.cli;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import picocli.CommandLine;
|
||||
import sonia.scm.cli.ParentCommand;
|
||||
import sonia.scm.repository.Namespace;
|
||||
import sonia.scm.repository.NamespaceManager;
|
||||
import sonia.scm.repository.RepositoryRoleManager;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
@CommandLine.Command(name = "remove-permissions")
|
||||
@ParentCommand(value = NamespaceCommand.class)
|
||||
class NamespacePermissionsRemoveCommand extends PermissionsRemoveCommand<Namespace> {
|
||||
|
||||
@CommandLine.Parameters(paramLabel = "namespace", index = "0", descriptionKey = "scm.namespace.remove-permissions.namespace")
|
||||
private String namespace;
|
||||
@Inject
|
||||
public NamespacePermissionsRemoveCommand(NamespaceManager namespaceManager, RepositoryRoleManager roleManager, RepositoryTemplateRenderer templateRenderer) {
|
||||
super(roleManager, templateRenderer, new NamespacePermissionBaseAdapter(namespaceManager, templateRenderer));
|
||||
}
|
||||
|
||||
@Override
|
||||
String getIdentifier() {
|
||||
return namespace;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void setNamespace(String namespace) {
|
||||
this.namespace = namespace;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020-present Cloudogu GmbH and Contributors
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package sonia.scm.repository.cli;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import picocli.CommandLine;
|
||||
import sonia.scm.cli.ParentCommand;
|
||||
import sonia.scm.repository.Namespace;
|
||||
import sonia.scm.repository.NamespaceManager;
|
||||
import sonia.scm.repository.RepositoryRoleManager;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
@CommandLine.Command(name = "set-role")
|
||||
@ParentCommand(value = NamespaceCommand.class)
|
||||
class NamespacePermissionsSetRoleCommand extends PermissionsSetRoleCommand<Namespace> {
|
||||
|
||||
@CommandLine.Parameters(paramLabel = "namespace", index = "0", descriptionKey = "scm.namespace.set-role.namespace")
|
||||
private String namespace;
|
||||
|
||||
@Inject
|
||||
public NamespacePermissionsSetRoleCommand(NamespaceManager namespaceManager, RepositoryRoleManager roleManager, RepositoryTemplateRenderer templateRenderer) {
|
||||
super(roleManager, templateRenderer, new NamespacePermissionBaseAdapter(namespaceManager, templateRenderer));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getIdentifier() {
|
||||
return namespace;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void setNamespace(String namespace) {
|
||||
this.namespace = namespace;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020-present Cloudogu GmbH and Contributors
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package sonia.scm.repository.cli;
|
||||
|
||||
import sonia.scm.repository.RepositoryPermissionHolder;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
public interface PermissionBaseAdapter<T extends RepositoryPermissionHolder> {
|
||||
|
||||
Optional<T> get(String identifier);
|
||||
|
||||
void modify(T object);
|
||||
}
|
||||
@@ -25,10 +25,8 @@
|
||||
package sonia.scm.repository.cli;
|
||||
|
||||
import picocli.CommandLine;
|
||||
import sonia.scm.repository.NamespaceAndName;
|
||||
import sonia.scm.repository.Repository;
|
||||
import sonia.scm.repository.RepositoryManager;
|
||||
import sonia.scm.repository.RepositoryPermission;
|
||||
import sonia.scm.repository.RepositoryPermissionHolder;
|
||||
import sonia.scm.repository.RepositoryRoleManager;
|
||||
|
||||
import javax.inject.Inject;
|
||||
@@ -37,64 +35,60 @@ import java.util.HashSet;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
class RepositoryPermissionBaseCommand {
|
||||
abstract class PermissionBaseCommand<T extends RepositoryPermissionHolder> {
|
||||
|
||||
private final RepositoryManager repositoryManager;
|
||||
private final RepositoryRoleManager roleManager;
|
||||
@CommandLine.Mixin
|
||||
private final RepositoryTemplateRenderer templateRenderer;
|
||||
private final PermissionBaseAdapter<T> adapter;
|
||||
|
||||
@Inject
|
||||
RepositoryPermissionBaseCommand(RepositoryManager repositoryManager, RepositoryRoleManager roleManager, RepositoryTemplateRenderer templateRenderer) {
|
||||
this.repositoryManager = repositoryManager;
|
||||
PermissionBaseCommand(RepositoryRoleManager roleManager, RepositoryTemplateRenderer templateRenderer, PermissionBaseAdapter<T> adapter) {
|
||||
this.roleManager = roleManager;
|
||||
this.templateRenderer = templateRenderer;
|
||||
this.adapter = adapter;
|
||||
}
|
||||
|
||||
void modifyRepository(String repositoryName, Predicate<Repository> modifier) {
|
||||
NamespaceAndName namespaceAndName;
|
||||
try {
|
||||
namespaceAndName = NamespaceAndName.fromString(repositoryName);
|
||||
} catch (IllegalArgumentException e) {
|
||||
templateRenderer.renderInvalidInputError();
|
||||
return;
|
||||
}
|
||||
Optional<T> get(String identifier) {
|
||||
return adapter.get(identifier);
|
||||
}
|
||||
|
||||
Repository repository = repositoryManager.get(namespaceAndName);
|
||||
if (repository != null) {
|
||||
if (modifier.test(repository)) {
|
||||
repositoryManager.modify(repository);
|
||||
}
|
||||
} else {
|
||||
templateRenderer.renderNotFoundError();
|
||||
void set(T object) {
|
||||
adapter.modify(object);
|
||||
}
|
||||
|
||||
void modify(String identifier, Predicate<T> modifier) {
|
||||
Optional<T> ns = get(identifier);
|
||||
if (ns.isPresent() && modifier.test(ns.get())) {
|
||||
set(ns.get());
|
||||
}
|
||||
}
|
||||
|
||||
void replacePermission(Repository repository, RepositoryPermission permission) {
|
||||
this.removeExistingPermission(repository, permission.getName(), permission.isGroupPermission());
|
||||
repository.addPermission(permission);
|
||||
void replacePermission(T namespace, RepositoryPermission permission) {
|
||||
removeExistingPermission(namespace, permission.getName(), permission.isGroupPermission());
|
||||
namespace.addPermission(permission);
|
||||
}
|
||||
|
||||
void removeExistingPermission(Repository repository, String name, boolean forGroup) {
|
||||
void removeExistingPermission(T permissionHolder, String name, boolean forGroup) {
|
||||
if (!forGroup) {
|
||||
repository.findUserPermission(name).ifPresent(repository::removePermission);
|
||||
permissionHolder.findUserPermission(name).ifPresent(permissionHolder::removePermission);
|
||||
} else {
|
||||
repository.findGroupPermission(name).ifPresent(repository::removePermission);
|
||||
permissionHolder.findGroupPermission(name).ifPresent(permissionHolder::removePermission);
|
||||
}
|
||||
}
|
||||
|
||||
HashSet<String> getPermissionsAsModifiableSet(Repository repository, String name, boolean forGroup) {
|
||||
return this.getExistingPermissions(repository, name, forGroup)
|
||||
HashSet<String> getPermissionsAsModifiableSet(T permissionHolder, String name, boolean forGroup) {
|
||||
return getExistingPermissions(permissionHolder, name, forGroup)
|
||||
.map(this::getVerbs)
|
||||
.map(HashSet::new)
|
||||
.orElseGet(HashSet::new);
|
||||
}
|
||||
|
||||
private Optional<RepositoryPermission> getExistingPermissions(Repository repo, String name, boolean forGroup) {
|
||||
private Optional<RepositoryPermission> getExistingPermissions(T permissionHolder, String name, boolean forGroup) {
|
||||
if (!forGroup) {
|
||||
return repo.findUserPermission(name);
|
||||
return permissionHolder.findUserPermission(name);
|
||||
} else {
|
||||
return repo.findGroupPermission(name);
|
||||
return permissionHolder.findGroupPermission(name);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -110,7 +104,7 @@ class RepositoryPermissionBaseCommand {
|
||||
templateRenderer.renderRoleNotFoundError();
|
||||
}
|
||||
|
||||
void renderVerbNotFoundError() {
|
||||
templateRenderer.renderVerbNotFoundError();
|
||||
void renderVerbNotFoundError(String verb) {
|
||||
templateRenderer.renderVerbNotFoundError(verb);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020-present Cloudogu GmbH and Contributors
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package sonia.scm.repository.cli;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import picocli.CommandLine;
|
||||
import sonia.scm.repository.RepositoryPermissionHolder;
|
||||
import sonia.scm.repository.RepositoryRoleManager;
|
||||
|
||||
abstract class PermissionClearCommand<T extends RepositoryPermissionHolder> extends PermissionBaseCommand<T> implements Runnable {
|
||||
|
||||
@CommandLine.Parameters(paramLabel = "name", index = "1", descriptionKey = "scm.repo.clear-permissions.name")
|
||||
private String name;
|
||||
@CommandLine.Option(names = {"--group", "-g"}, descriptionKey = "scm.repo.clear-permissions.forGroup")
|
||||
private boolean forGroup;
|
||||
|
||||
PermissionClearCommand(RepositoryRoleManager roleManager, RepositoryTemplateRenderer templateRenderer, PermissionBaseAdapter<T> adapter) {
|
||||
super(roleManager, templateRenderer, adapter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
modify(
|
||||
getIdentifier(),
|
||||
ns -> {
|
||||
removeExistingPermission(ns, name, forGroup);
|
||||
return true;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
abstract String getIdentifier();
|
||||
|
||||
@VisibleForTesting
|
||||
void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void setForGroup(boolean forGroup) {
|
||||
this.forGroup = forGroup;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020-present Cloudogu GmbH and Contributors
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package sonia.scm.repository.cli;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import picocli.CommandLine;
|
||||
import sonia.scm.cli.PermissionDescriptionResolver;
|
||||
import sonia.scm.repository.RepositoryPermission;
|
||||
import sonia.scm.repository.RepositoryPermissionHolder;
|
||||
import sonia.scm.repository.RepositoryRoleManager;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Set;
|
||||
|
||||
import static java.util.Arrays.asList;
|
||||
|
||||
abstract class PermissionsAddCommand<T extends RepositoryPermissionHolder> extends PermissionBaseCommand<T> implements Runnable {
|
||||
|
||||
private final PermissionDescriptionResolver permissionDescriptionResolver;
|
||||
|
||||
@CommandLine.Parameters(paramLabel = "name", index = "1", descriptionKey = "scm.repo.add-permissions.name")
|
||||
private String name;
|
||||
@CommandLine.Parameters(paramLabel = "verbs", index = "2..", arity = "1..", descriptionKey = "scm.repo.add-permissions.verbs")
|
||||
private String[] verbs = new String[0];
|
||||
@CommandLine.Option(names = {"--group", "-g"}, descriptionKey = "scm.repo.add-permissions.forGroup")
|
||||
private boolean forGroup;
|
||||
|
||||
PermissionsAddCommand(RepositoryRoleManager roleManager, PermissionDescriptionResolver permissionDescriptionResolver, RepositoryTemplateRenderer templateRenderer, PermissionBaseAdapter<T> adapter) {
|
||||
super(roleManager, templateRenderer, adapter);
|
||||
this.permissionDescriptionResolver = permissionDescriptionResolver;
|
||||
}
|
||||
|
||||
abstract String getIdentifier();
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
modify(
|
||||
getIdentifier(),
|
||||
ns -> {
|
||||
if (!Arrays.stream(verbs).allMatch(this::verifyVerbExists)) {
|
||||
return false;
|
||||
}
|
||||
Set<String> resultingVerbs =
|
||||
getPermissionsAsModifiableSet(ns, name, forGroup);
|
||||
if (resultingVerbs.containsAll(asList(this.verbs))) {
|
||||
return false;
|
||||
}
|
||||
resultingVerbs.addAll(asList(this.verbs));
|
||||
replacePermission(ns, new RepositoryPermission(name, resultingVerbs, forGroup));
|
||||
return true;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
private boolean verifyVerbExists(String verb) {
|
||||
if (permissionDescriptionResolver.getDescription(verb).isEmpty()) {
|
||||
renderVerbNotFoundError(verb);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void setVerbs(String... verbs) {
|
||||
this.verbs = verbs;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void setForGroup(boolean forGroup) {
|
||||
this.forGroup = forGroup;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020-present Cloudogu GmbH and Contributors
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package sonia.scm.repository.cli;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import picocli.CommandLine;
|
||||
import sonia.scm.cli.PermissionDescriptionResolver;
|
||||
import sonia.scm.repository.RepositoryRole;
|
||||
import sonia.scm.repository.RepositoryRoleManager;
|
||||
import sonia.scm.security.RepositoryPermissionProvider;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static java.util.stream.Collectors.toList;
|
||||
|
||||
class PermissionsAvailableCommand implements Runnable {
|
||||
|
||||
@CommandLine.Option(names = {"--roles", "-r"}, descriptionKey = "scm.repo.available-permissions.roles-only")
|
||||
private boolean roles;
|
||||
@CommandLine.Option(names = {"--verbs", "-v"}, descriptionKey = "scm.repo.available-permissions.verbs-only")
|
||||
private boolean verbs;
|
||||
|
||||
@CommandLine.Mixin
|
||||
private final RepositoryTemplateRenderer templateRenderer;
|
||||
private final RepositoryPermissionProvider repositoryPermissionProvider;
|
||||
private final PermissionDescriptionResolver permissionDescriptionResolver;
|
||||
private final RepositoryRoleManager repositoryRoleManager;
|
||||
|
||||
public PermissionsAvailableCommand(RepositoryTemplateRenderer templateRenderer, RepositoryPermissionProvider repositoryPermissionProvider, PermissionDescriptionResolver permissionDescriptionResolver, RepositoryRoleManager repositoryRoleManager) {
|
||||
this.templateRenderer = templateRenderer;
|
||||
this.repositoryPermissionProvider = repositoryPermissionProvider;
|
||||
this.permissionDescriptionResolver = permissionDescriptionResolver;
|
||||
this.repositoryRoleManager = repositoryRoleManager;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void setRoles(boolean roles) {
|
||||
this.roles = roles;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void setVerbs(boolean verbs) {
|
||||
this.verbs = verbs;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
if (roles) {
|
||||
templateRenderer.renderRoles(getRoleBeans());
|
||||
} else if (verbs) {
|
||||
templateRenderer.renderVerbs(getVerbBeans());
|
||||
} else {
|
||||
templateRenderer.render(getRoleBeans(), getVerbBeans());
|
||||
}
|
||||
}
|
||||
|
||||
private List<VerbBean> getVerbBeans() {
|
||||
return repositoryPermissionProvider.availableVerbs().stream().map(this::createBean).collect(toList());
|
||||
}
|
||||
|
||||
private List<RoleBean> getRoleBeans() {
|
||||
return repositoryRoleManager.getAll().stream().map(this::createBean).collect(toList());
|
||||
}
|
||||
|
||||
private VerbBean createBean(String verb) {
|
||||
return new VerbBean(verb, permissionDescriptionResolver.getDescription(verb).orElse(verb));
|
||||
}
|
||||
|
||||
private RoleBean createBean(RepositoryRole role) {
|
||||
return new RoleBean(role.getName(), role.getVerbs());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020-present Cloudogu GmbH and Contributors
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package sonia.scm.repository.cli;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import picocli.CommandLine;
|
||||
import sonia.scm.cli.CommandValidator;
|
||||
import sonia.scm.repository.RepositoryPermissionHolder;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Optional;
|
||||
|
||||
abstract class PermissionsListCommand<T extends RepositoryPermissionHolder> implements Runnable {
|
||||
|
||||
@CommandLine.Mixin
|
||||
private final RepositoryTemplateRenderer templateRenderer;
|
||||
@CommandLine.Mixin
|
||||
private final CommandValidator validator;
|
||||
private final PermissionBaseAdapter<T> adapter;
|
||||
private final RepositoryPermissionBeanMapper beanMapper;
|
||||
|
||||
@CommandLine.Option(names = {"--verbose", "-v"}, descriptionKey = "scm.repo.list-permissions.verbose")
|
||||
private boolean verbose;
|
||||
@CommandLine.Option(names = {"--keys", "-k"}, descriptionKey = "scm.repo.list-permissions.keys")
|
||||
private boolean keys;
|
||||
|
||||
PermissionsListCommand(RepositoryTemplateRenderer templateRenderer, CommandValidator validator, PermissionBaseAdapter<T> adapter, RepositoryPermissionBeanMapper beanMapper) {
|
||||
this.templateRenderer = templateRenderer;
|
||||
this.validator = validator;
|
||||
this.adapter = adapter;
|
||||
this.beanMapper = beanMapper;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void setVerbose(boolean verbose) {
|
||||
this.verbose = verbose;
|
||||
}
|
||||
|
||||
public void setKeys(boolean keys) {
|
||||
this.keys = keys;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
validator.validate();
|
||||
Optional<T> object = adapter.get(getIdentifier());
|
||||
if (object.isPresent()) {
|
||||
Collection<RepositoryPermissionBean> permissions = beanMapper.createPermissionBeans(object.get().getPermissions(), keys);
|
||||
if (verbose) {
|
||||
templateRenderer.renderVerbose(permissions);
|
||||
} else {
|
||||
templateRenderer.render(permissions);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
abstract String getIdentifier();
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020-present Cloudogu GmbH and Contributors
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package sonia.scm.repository.cli;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import picocli.CommandLine;
|
||||
import sonia.scm.repository.RepositoryPermission;
|
||||
import sonia.scm.repository.RepositoryPermissionHolder;
|
||||
import sonia.scm.repository.RepositoryRoleManager;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import static java.util.Arrays.asList;
|
||||
|
||||
abstract class PermissionsRemoveCommand<T extends RepositoryPermissionHolder> extends PermissionBaseCommand<T> implements Runnable {
|
||||
|
||||
@CommandLine.Parameters(paramLabel = "name", index = "1", descriptionKey = "scm.repo.remove-permissions.name")
|
||||
private String name;
|
||||
@CommandLine.Parameters(paramLabel = "verbs", index = "2..", arity = "1..", descriptionKey = "scm.repo.remove-permissions.verbs")
|
||||
private String[] verbs = new String[0];
|
||||
|
||||
@CommandLine.Option(names = {"--group", "-g"}, descriptionKey = "scm.repo.remove-permissions.forGroup")
|
||||
private boolean forGroup;
|
||||
|
||||
PermissionsRemoveCommand(RepositoryRoleManager roleManager, RepositoryTemplateRenderer templateRenderer, PermissionBaseAdapter<T> adapter) {
|
||||
super(roleManager, templateRenderer, adapter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
modify(
|
||||
getIdentifier(),
|
||||
ns -> {
|
||||
Set<String> resultingVerbs =
|
||||
getPermissionsAsModifiableSet(ns, name, forGroup);
|
||||
if (resultingVerbs.stream().noneMatch(verb -> asList(verbs).contains(verb))) {
|
||||
return false;
|
||||
}
|
||||
resultingVerbs.removeAll(asList(this.verbs));
|
||||
replacePermission(ns, new RepositoryPermission(name, resultingVerbs, forGroup));
|
||||
return true;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
abstract String getIdentifier();
|
||||
|
||||
@VisibleForTesting
|
||||
void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void setVerbs(String... verbs) {
|
||||
this.verbs = verbs;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void setForGroup(boolean forGroup) {
|
||||
this.forGroup = forGroup;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020-present Cloudogu GmbH and Contributors
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package sonia.scm.repository.cli;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import picocli.CommandLine;
|
||||
import sonia.scm.repository.RepositoryPermission;
|
||||
import sonia.scm.repository.RepositoryPermissionHolder;
|
||||
import sonia.scm.repository.RepositoryRoleManager;
|
||||
|
||||
abstract class PermissionsSetRoleCommand<T extends RepositoryPermissionHolder> extends PermissionBaseCommand<T> implements Runnable {
|
||||
|
||||
private final RepositoryRoleManager roleManager;
|
||||
|
||||
@CommandLine.Parameters(paramLabel = "name", index = "1", descriptionKey = "scm.repo.set-role.name")
|
||||
private String name;
|
||||
@CommandLine.Parameters(paramLabel = "role", index = "2", descriptionKey = "scm.repo.set-role.role")
|
||||
private String role;
|
||||
@CommandLine.Option(names = {"--group", "-g"}, descriptionKey = "scm.repo.set-role.forGroup")
|
||||
private boolean forGroup;
|
||||
|
||||
PermissionsSetRoleCommand(RepositoryRoleManager roleManager, RepositoryTemplateRenderer templateRenderer, PermissionBaseAdapter<T> adapter) {
|
||||
super(roleManager, templateRenderer, adapter);
|
||||
this.roleManager = roleManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
modify(
|
||||
getIdentifier(),
|
||||
ns -> {
|
||||
if (roleManager.get(role) == null) {
|
||||
renderRoleNotFoundError();
|
||||
return false;
|
||||
}
|
||||
replacePermission(ns, new RepositoryPermission(name, role, forGroup));
|
||||
return true;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
protected abstract String getIdentifier();
|
||||
|
||||
@VisibleForTesting
|
||||
void setRole(String role) {
|
||||
this.role = role;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void setForGroup(boolean forGroup) {
|
||||
this.forGroup = forGroup;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020-present Cloudogu GmbH and Contributors
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package sonia.scm.repository.cli;
|
||||
|
||||
import sonia.scm.repository.NamespaceAndName;
|
||||
import sonia.scm.repository.Repository;
|
||||
import sonia.scm.repository.RepositoryManager;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import static java.util.Optional.empty;
|
||||
import static java.util.Optional.of;
|
||||
|
||||
class RepositoryPermissionBaseAdapter implements PermissionBaseAdapter<Repository> {
|
||||
|
||||
private final RepositoryManager repositoryManager;
|
||||
private final RepositoryTemplateRenderer templateRenderer;
|
||||
|
||||
RepositoryPermissionBaseAdapter(RepositoryManager repositoryManager, RepositoryTemplateRenderer templateRenderer) {
|
||||
this.repositoryManager = repositoryManager;
|
||||
this.templateRenderer = templateRenderer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<Repository> get(String repositoryNamespaceAndName) {
|
||||
NamespaceAndName namespaceAndName;
|
||||
try {
|
||||
namespaceAndName = NamespaceAndName.fromString(repositoryNamespaceAndName);
|
||||
} catch (IllegalArgumentException e) {
|
||||
templateRenderer.renderInvalidInputError();
|
||||
return empty();
|
||||
}
|
||||
Repository repository = repositoryManager.get(namespaceAndName);
|
||||
if (repository == null) {
|
||||
templateRenderer.renderNotFoundError();
|
||||
return empty();
|
||||
} else {
|
||||
return of(repository);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void modify(Repository repository) {
|
||||
repositoryManager.modify(repository);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020-present Cloudogu GmbH and Contributors
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package sonia.scm.repository.cli;
|
||||
|
||||
import sonia.scm.cli.PermissionDescriptionResolver;
|
||||
import sonia.scm.repository.RepositoryPermission;
|
||||
import sonia.scm.repository.RepositoryRoleManager;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.util.Collection;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static java.util.stream.Collectors.toList;
|
||||
|
||||
class RepositoryPermissionBeanMapper {
|
||||
|
||||
private final RepositoryRoleManager roleManager;
|
||||
private final PermissionDescriptionResolver permissionDescriptionResolver;
|
||||
|
||||
@Inject
|
||||
RepositoryPermissionBeanMapper(RepositoryRoleManager roleManager, PermissionDescriptionResolver permissionDescriptionResolver) {
|
||||
this.roleManager = roleManager;
|
||||
this.permissionDescriptionResolver = permissionDescriptionResolver;
|
||||
}
|
||||
|
||||
Collection<RepositoryPermissionBean> createPermissionBeans(Collection<RepositoryPermission> permissions, boolean keys) {
|
||||
return permissions
|
||||
.stream()
|
||||
.map(permission -> createPermissionBean(permission, keys))
|
||||
.collect(toList());
|
||||
}
|
||||
|
||||
private RepositoryPermissionBean createPermissionBean(RepositoryPermission permission, boolean keys) {
|
||||
Collection<String> effectiveVerbs;
|
||||
if (permission.getRole() == null) {
|
||||
effectiveVerbs = permission.getVerbs();
|
||||
} else {
|
||||
effectiveVerbs = roleManager.get(permission.getRole()).getVerbs();
|
||||
}
|
||||
return new RepositoryPermissionBean(
|
||||
permission.isGroupPermission(),
|
||||
permission.getName(),
|
||||
permission.getRole() == null? "CUSTOM": permission.getRole(),
|
||||
keys? effectiveVerbs: getDescriptions(effectiveVerbs)
|
||||
);
|
||||
}
|
||||
|
||||
private Collection<String> getDescriptions(Collection<String> effectiveVerbs) {
|
||||
return effectiveVerbs.stream().map(this::getDescription).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private String getDescription(String verb) {
|
||||
return permissionDescriptionResolver.getDescription(verb).orElse(verb);
|
||||
}
|
||||
}
|
||||
@@ -28,82 +28,31 @@ import com.google.common.annotations.VisibleForTesting;
|
||||
import picocli.CommandLine;
|
||||
import sonia.scm.cli.ParentCommand;
|
||||
import sonia.scm.cli.PermissionDescriptionResolver;
|
||||
import sonia.scm.repository.Repository;
|
||||
import sonia.scm.repository.RepositoryManager;
|
||||
import sonia.scm.repository.RepositoryPermission;
|
||||
import sonia.scm.repository.RepositoryRoleManager;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.util.Arrays;
|
||||
import java.util.Set;
|
||||
|
||||
import static java.util.Arrays.asList;
|
||||
|
||||
@CommandLine.Command(name = "add-permissions")
|
||||
@ParentCommand(value = RepositoryCommand.class)
|
||||
class RepositoryPermissionsAddCommand extends RepositoryPermissionBaseCommand implements Runnable {
|
||||
|
||||
private final PermissionDescriptionResolver permissionDescriptionResolver;
|
||||
class RepositoryPermissionsAddCommand extends PermissionsAddCommand<Repository> implements Runnable {
|
||||
|
||||
@CommandLine.Parameters(paramLabel = "namespace/name", index = "0", descriptionKey = "scm.repo.add-permissions.repository")
|
||||
private String repositoryName;
|
||||
@CommandLine.Parameters(paramLabel = "name", index = "1", descriptionKey = "scm.repo.add-permissions.name")
|
||||
private String name;
|
||||
@CommandLine.Parameters(paramLabel = "verbs", index = "2..", arity = "1..", descriptionKey = "scm.repo.add-permissions.verbs")
|
||||
private String[] verbs = new String[0];
|
||||
|
||||
@CommandLine.Option(names = {"--group", "-g"}, descriptionKey = "scm.repo.add-permissions.forGroup")
|
||||
private boolean forGroup;
|
||||
private String repositoryNamespaceAndName;
|
||||
|
||||
@Inject
|
||||
RepositoryPermissionsAddCommand(RepositoryManager repositoryManager, RepositoryPermissionBaseCommand permissionCommandManager, RepositoryRoleManager roleManager, PermissionDescriptionResolver permissionDescriptionResolver, RepositoryTemplateRenderer templateRenderer) {
|
||||
super(repositoryManager, roleManager, templateRenderer);
|
||||
this.permissionDescriptionResolver = permissionDescriptionResolver;
|
||||
RepositoryPermissionsAddCommand(RepositoryManager repositoryManager, RepositoryRoleManager roleManager, PermissionDescriptionResolver permissionDescriptionResolver, RepositoryTemplateRenderer templateRenderer) {
|
||||
super(roleManager, permissionDescriptionResolver, templateRenderer, new RepositoryPermissionBaseAdapter(repositoryManager, templateRenderer));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
modifyRepository(
|
||||
repositoryName,
|
||||
repository -> {
|
||||
if (!Arrays.stream(verbs).allMatch(this::verifyVerbExists)) {
|
||||
return false;
|
||||
}
|
||||
Set<String> resultingVerbs =
|
||||
getPermissionsAsModifiableSet(repository, name, forGroup);
|
||||
if (resultingVerbs.containsAll(asList(this.verbs))) {
|
||||
return false;
|
||||
}
|
||||
resultingVerbs.addAll(asList(this.verbs));
|
||||
replacePermission(repository, new RepositoryPermission(name, resultingVerbs, forGroup));
|
||||
return true;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
private boolean verifyVerbExists(String verb) {
|
||||
if (permissionDescriptionResolver.getDescription(verb).isEmpty()) {
|
||||
renderVerbNotFoundError();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
String getIdentifier() {
|
||||
return repositoryNamespaceAndName;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void setRepositoryName(String repositoryName) {
|
||||
this.repositoryName = repositoryName;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void setVerbs(String... verbs) {
|
||||
this.verbs = verbs;
|
||||
}
|
||||
|
||||
public void setForGroup(boolean forGroup) {
|
||||
this.forGroup = forGroup;
|
||||
void setRepositoryNamespaceAndName(String repositoryNamespaceAndName) {
|
||||
this.repositoryNamespaceAndName = repositoryNamespaceAndName;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,76 +24,20 @@
|
||||
|
||||
package sonia.scm.repository.cli;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import picocli.CommandLine;
|
||||
import sonia.scm.cli.ParentCommand;
|
||||
import sonia.scm.cli.PermissionDescriptionResolver;
|
||||
import sonia.scm.repository.RepositoryRole;
|
||||
import sonia.scm.repository.RepositoryRoleManager;
|
||||
import sonia.scm.security.RepositoryPermissionProvider;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.util.List;
|
||||
|
||||
import static java.util.stream.Collectors.toList;
|
||||
|
||||
@CommandLine.Command(name = "available-permissions")
|
||||
@ParentCommand(value = RepositoryCommand.class)
|
||||
class RepositoryPermissionsAvailableCommand implements Runnable {
|
||||
|
||||
@CommandLine.Option(names = {"--roles", "-r"}, descriptionKey = "scm.repo.available-permissions.roles-only")
|
||||
private boolean roles;
|
||||
@CommandLine.Option(names = {"--verbs", "-v"}, descriptionKey = "scm.repo.available-permissions.verbs-only")
|
||||
private boolean verbs;
|
||||
|
||||
@CommandLine.Mixin
|
||||
private final RepositoryTemplateRenderer templateRenderer;
|
||||
private final RepositoryPermissionProvider repositoryPermissionProvider;
|
||||
private final PermissionDescriptionResolver permissionDescriptionResolver;
|
||||
private final RepositoryRoleManager repositoryRoleManager;
|
||||
class RepositoryPermissionsAvailableCommand extends PermissionsAvailableCommand {
|
||||
|
||||
@Inject
|
||||
public RepositoryPermissionsAvailableCommand(RepositoryTemplateRenderer templateRenderer, RepositoryPermissionProvider repositoryPermissionProvider, PermissionDescriptionResolver permissionDescriptionResolver, RepositoryRoleManager repositoryRoleManager) {
|
||||
this.templateRenderer = templateRenderer;
|
||||
this.repositoryPermissionProvider = repositoryPermissionProvider;
|
||||
this.permissionDescriptionResolver = permissionDescriptionResolver;
|
||||
this.repositoryRoleManager = repositoryRoleManager;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void setRoles(boolean roles) {
|
||||
this.roles = roles;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void setVerbs(boolean verbs) {
|
||||
this.verbs = verbs;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
if (roles) {
|
||||
templateRenderer.renderRoles(getRoleBeans());
|
||||
} else if (verbs) {
|
||||
templateRenderer.renderVerbs(getVerbBeans());
|
||||
} else {
|
||||
templateRenderer.render(getRoleBeans(), getVerbBeans());
|
||||
}
|
||||
}
|
||||
|
||||
private List<VerbBean> getVerbBeans() {
|
||||
return repositoryPermissionProvider.availableVerbs().stream().map(this::createBean).collect(toList());
|
||||
}
|
||||
|
||||
private List<RoleBean> getRoleBeans() {
|
||||
return repositoryRoleManager.getAll().stream().map(this::createBean).collect(toList());
|
||||
}
|
||||
|
||||
private VerbBean createBean(String verb) {
|
||||
return new VerbBean(verb, permissionDescriptionResolver.getDescription(verb).orElse(verb));
|
||||
}
|
||||
|
||||
private RoleBean createBean(RepositoryRole role) {
|
||||
return new RoleBean(role.getName(), role.getVerbs());
|
||||
super(templateRenderer, repositoryPermissionProvider, permissionDescriptionResolver, repositoryRoleManager);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@ package sonia.scm.repository.cli;
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import picocli.CommandLine;
|
||||
import sonia.scm.cli.ParentCommand;
|
||||
import sonia.scm.repository.Repository;
|
||||
import sonia.scm.repository.RepositoryManager;
|
||||
import sonia.scm.repository.RepositoryRoleManager;
|
||||
|
||||
@@ -34,43 +35,23 @@ import javax.inject.Inject;
|
||||
|
||||
@CommandLine.Command(name = "clear-permissions")
|
||||
@ParentCommand(value = RepositoryCommand.class)
|
||||
class RepositoryPermissionsClearCommand extends RepositoryPermissionBaseCommand implements Runnable {
|
||||
class RepositoryPermissionsClearCommand extends PermissionClearCommand<Repository> {
|
||||
|
||||
@CommandLine.Parameters(paramLabel = "namespace/name", index = "0", descriptionKey = "scm.repo.clear-permissions.repository")
|
||||
private String repositoryName;
|
||||
@CommandLine.Parameters(paramLabel = "name", index = "1", descriptionKey = "scm.repo.clear-permissions.name")
|
||||
private String name;
|
||||
|
||||
@CommandLine.Option(names = {"--group", "-g"}, descriptionKey = "scm.repo.clear-permissions.forGroup")
|
||||
private boolean forGroup;
|
||||
private String repositoryNamespaceAndName;
|
||||
|
||||
@Inject
|
||||
public RepositoryPermissionsClearCommand(RepositoryManager repositoryManager, RepositoryRoleManager roleManager, RepositoryTemplateRenderer templateRenderer) {
|
||||
super(repositoryManager, roleManager, templateRenderer);
|
||||
super(roleManager, templateRenderer, new RepositoryPermissionBaseAdapter(repositoryManager, templateRenderer));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
modifyRepository(
|
||||
repositoryName,
|
||||
repo -> {
|
||||
removeExistingPermission(repo, name, forGroup);
|
||||
return true;
|
||||
}
|
||||
);
|
||||
String getIdentifier() {
|
||||
return repositoryNamespaceAndName;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void setRepositoryName(String repositoryName) {
|
||||
this.repositoryName = repositoryName;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public void setForGroup(boolean forGroup) {
|
||||
this.forGroup = forGroup;
|
||||
void setRepositoryNamespaceAndName(String repositoryNamespaceAndName) {
|
||||
this.repositoryNamespaceAndName = repositoryNamespaceAndName;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,102 +28,30 @@ import com.google.common.annotations.VisibleForTesting;
|
||||
import picocli.CommandLine;
|
||||
import sonia.scm.cli.CommandValidator;
|
||||
import sonia.scm.cli.ParentCommand;
|
||||
import sonia.scm.cli.PermissionDescriptionResolver;
|
||||
import sonia.scm.repository.NamespaceAndName;
|
||||
import sonia.scm.repository.Repository;
|
||||
import sonia.scm.repository.RepositoryManager;
|
||||
import sonia.scm.repository.RepositoryPermission;
|
||||
import sonia.scm.repository.RepositoryRoleManager;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.util.Collection;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@CommandLine.Command(name = "list-permissions")
|
||||
@ParentCommand(value = RepositoryCommand.class)
|
||||
class RepositoryPermissionsListCommand implements Runnable {
|
||||
|
||||
@CommandLine.Mixin
|
||||
private final RepositoryTemplateRenderer templateRenderer;
|
||||
@CommandLine.Mixin
|
||||
private final CommandValidator validator;
|
||||
private final RepositoryManager manager;
|
||||
private final RepositoryRoleManager roleManager;
|
||||
private final PermissionDescriptionResolver permissionDescriptionResolver;
|
||||
class RepositoryPermissionsListCommand extends PermissionsListCommand<Repository> {
|
||||
|
||||
@CommandLine.Parameters(paramLabel = "namespace/name", index = "0", descriptionKey = "scm.repo.list-permissions.repository")
|
||||
private String repository;
|
||||
@CommandLine.Option(names = {"--verbose", "-v"}, descriptionKey = "scm.repo.list-permissions.verbose")
|
||||
private boolean verbose;
|
||||
@CommandLine.Option(names = {"--keys", "-k"}, descriptionKey = "scm.repo.list-permissions.keys")
|
||||
private boolean keys;
|
||||
|
||||
@Inject
|
||||
public RepositoryPermissionsListCommand(RepositoryTemplateRenderer templateRenderer, CommandValidator validator, RepositoryManager manager, RepositoryRoleManager roleManager, PermissionDescriptionResolver permissionDescriptionResolver) {
|
||||
this.templateRenderer = templateRenderer;
|
||||
this.validator = validator;
|
||||
this.manager = manager;
|
||||
this.roleManager = roleManager;
|
||||
this.permissionDescriptionResolver = permissionDescriptionResolver;
|
||||
public RepositoryPermissionsListCommand(RepositoryTemplateRenderer templateRenderer, CommandValidator validator, RepositoryManager manager, RepositoryPermissionBeanMapper beanMapper) {
|
||||
super(templateRenderer, validator, new RepositoryPermissionBaseAdapter(manager, templateRenderer), beanMapper);
|
||||
}
|
||||
|
||||
@Override
|
||||
String getIdentifier() {
|
||||
return repository;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void setRepository(String repository) {
|
||||
this.repository = repository;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void setVerbose(boolean verbose) {
|
||||
this.verbose = verbose;
|
||||
}
|
||||
|
||||
public void setKeys(boolean keys) {
|
||||
this.keys = keys;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
validator.validate();
|
||||
String[] splitRepo = repository.split("/");
|
||||
if (splitRepo.length == 2) {
|
||||
Repository repo = manager.get(new NamespaceAndName(splitRepo[0], splitRepo[1]));
|
||||
|
||||
if (repo != null) {
|
||||
Collection<RepositoryPermissionBean> permissions =
|
||||
repo.getPermissions().stream().map(this::createPermissionBean).collect(Collectors.toList());
|
||||
if (verbose) {
|
||||
templateRenderer.renderVerbose(permissions);
|
||||
} else {
|
||||
templateRenderer.render(permissions);
|
||||
}
|
||||
} else {
|
||||
templateRenderer.renderNotFoundError();
|
||||
}
|
||||
} else {
|
||||
templateRenderer.renderInvalidInputError();
|
||||
}
|
||||
}
|
||||
|
||||
private RepositoryPermissionBean createPermissionBean(RepositoryPermission permission) {
|
||||
Collection<String> effectiveVerbs;
|
||||
if (permission.getRole() == null) {
|
||||
effectiveVerbs = permission.getVerbs();
|
||||
} else {
|
||||
effectiveVerbs = roleManager.get(permission.getRole()).getVerbs();
|
||||
}
|
||||
return new RepositoryPermissionBean(
|
||||
permission.isGroupPermission(),
|
||||
permission.getName(),
|
||||
permission.getRole() == null? "CUSTOM": permission.getRole(),
|
||||
keys? effectiveVerbs: getDescriptions(effectiveVerbs)
|
||||
);
|
||||
}
|
||||
|
||||
private Collection<String> getDescriptions(Collection<String> effectiveVerbs) {
|
||||
return effectiveVerbs.stream().map(this::getDescription).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private String getDescription(String verb) {
|
||||
return permissionDescriptionResolver.getDescription(verb).orElse(verb);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,66 +27,31 @@ package sonia.scm.repository.cli;
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import picocli.CommandLine;
|
||||
import sonia.scm.cli.ParentCommand;
|
||||
import sonia.scm.repository.Repository;
|
||||
import sonia.scm.repository.RepositoryManager;
|
||||
import sonia.scm.repository.RepositoryPermission;
|
||||
import sonia.scm.repository.RepositoryRoleManager;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.util.Set;
|
||||
|
||||
import static java.util.Arrays.asList;
|
||||
|
||||
@CommandLine.Command(name = "remove-permissions")
|
||||
@ParentCommand(value = RepositoryCommand.class)
|
||||
class RepositoryPermissionsRemoveCommand extends RepositoryPermissionBaseCommand implements Runnable {
|
||||
class RepositoryPermissionsRemoveCommand extends PermissionsRemoveCommand<Repository> {
|
||||
|
||||
@CommandLine.Parameters(paramLabel = "namespace/name", index = "0", descriptionKey = "scm.repo.remove-permissions.repository")
|
||||
private String repositoryName;
|
||||
@CommandLine.Parameters(paramLabel = "name", index = "1", descriptionKey = "scm.repo.remove-permissions.name")
|
||||
private String name;
|
||||
@CommandLine.Parameters(paramLabel = "verbs", index = "2..", arity = "1..", descriptionKey = "scm.repo.remove-permissions.verbs")
|
||||
private String[] verbs = new String[0];
|
||||
|
||||
@CommandLine.Option(names = {"--group", "-g"}, descriptionKey = "scm.repo.remove-permissions.forGroup")
|
||||
private boolean forGroup;
|
||||
private String repositoryNamespaceAndName;
|
||||
|
||||
@Inject
|
||||
public RepositoryPermissionsRemoveCommand(RepositoryManager repositoryManager, RepositoryRoleManager roleManager, RepositoryTemplateRenderer templateRenderer) {
|
||||
super(repositoryManager, roleManager, templateRenderer);
|
||||
super(roleManager, templateRenderer, new RepositoryPermissionBaseAdapter(repositoryManager, templateRenderer));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
modifyRepository(
|
||||
repositoryName,
|
||||
repository -> {
|
||||
Set<String> resultingVerbs =
|
||||
getPermissionsAsModifiableSet(repository, name, forGroup);
|
||||
if (resultingVerbs.stream().noneMatch(verb -> asList(verbs).contains(verb))) {
|
||||
return false;
|
||||
}
|
||||
resultingVerbs.removeAll(asList(this.verbs));
|
||||
replacePermission(repository, new RepositoryPermission(name, resultingVerbs, forGroup));
|
||||
return true;
|
||||
}
|
||||
);
|
||||
String getIdentifier() {
|
||||
return repositoryNamespaceAndName;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void setRepositoryName(String repositoryName) {
|
||||
this.repositoryName = repositoryName;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public void setVerbs(String... verbs) {
|
||||
this.verbs = verbs;
|
||||
}
|
||||
|
||||
public void setForGroup(boolean forGroup) {
|
||||
this.forGroup = forGroup;
|
||||
void setRepositoryNamespaceAndName(String repositoryNamespaceAndName) {
|
||||
this.repositoryNamespaceAndName = repositoryNamespaceAndName;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,65 +27,31 @@ package sonia.scm.repository.cli;
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import picocli.CommandLine;
|
||||
import sonia.scm.cli.ParentCommand;
|
||||
import sonia.scm.repository.Repository;
|
||||
import sonia.scm.repository.RepositoryManager;
|
||||
import sonia.scm.repository.RepositoryPermission;
|
||||
import sonia.scm.repository.RepositoryRoleManager;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
@CommandLine.Command(name = "set-role")
|
||||
@ParentCommand(value = RepositoryCommand.class)
|
||||
class RepositoryPermissionsSetRoleCommand extends RepositoryPermissionBaseCommand implements Runnable {
|
||||
|
||||
private final RepositoryRoleManager roleManager;
|
||||
class RepositoryPermissionsSetRoleCommand extends PermissionsSetRoleCommand<Repository> {
|
||||
|
||||
@CommandLine.Parameters(paramLabel = "namespace/name", index = "0", descriptionKey = "scm.repo.set-role.repository")
|
||||
private String repositoryName;
|
||||
@CommandLine.Parameters(paramLabel = "name", index = "1", descriptionKey = "scm.repo.set-role.name")
|
||||
private String name;
|
||||
@CommandLine.Parameters(paramLabel = "role", index = "2", descriptionKey = "scm.repo.set-role.role")
|
||||
private String role;
|
||||
|
||||
@CommandLine.Option(names = {"--group", "-g"}, descriptionKey = "scm.repo.set-role.forGroup")
|
||||
private boolean forGroup;
|
||||
private String repositoryNamespaceAndName;
|
||||
|
||||
@Inject
|
||||
public RepositoryPermissionsSetRoleCommand(RepositoryManager repositoryManager, RepositoryRoleManager roleManager, RepositoryTemplateRenderer templateRenderer) {
|
||||
super(repositoryManager, roleManager, templateRenderer);
|
||||
this.roleManager = roleManager;
|
||||
super(roleManager, templateRenderer, new RepositoryPermissionBaseAdapter(repositoryManager, templateRenderer));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
modifyRepository(
|
||||
repositoryName,
|
||||
repository -> {
|
||||
if (roleManager.get(role) == null) {
|
||||
renderRoleNotFoundError();
|
||||
return false;
|
||||
}
|
||||
replacePermission(repository, new RepositoryPermission(name, role, forGroup));
|
||||
return true;
|
||||
}
|
||||
);
|
||||
protected String getIdentifier() {
|
||||
return repositoryNamespaceAndName;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void setRepositoryName(String repositoryName) {
|
||||
this.repositoryName = repositoryName;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void setRole(String role) {
|
||||
this.role = role;
|
||||
}
|
||||
|
||||
public void setForGroup(boolean forGroup) {
|
||||
this.forGroup = forGroup;
|
||||
void setRepositoryNamespaceAndName(String repositoryNamespaceAndName) {
|
||||
this.repositoryNamespaceAndName = repositoryNamespaceAndName;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -131,8 +131,8 @@ class RepositoryTemplateRenderer extends TemplateRenderer {
|
||||
context.exit(ExitCode.NOT_FOUND);
|
||||
}
|
||||
|
||||
void renderVerbNotFoundError() {
|
||||
renderToStderr("{{i18n.verbNotFound}}", emptyMap());
|
||||
void renderVerbNotFoundError(String verb) {
|
||||
renderToStderr("{{i18n.verbNotFound}}: {{verb}}", Map.of("verb", verb));
|
||||
context.getStderr().println();
|
||||
context.exit(ExitCode.NOT_FOUND);
|
||||
}
|
||||
|
||||
@@ -109,7 +109,7 @@ scm.repo.set-role.name = User or group name to set role for
|
||||
scm.repo.set-role.role = Permission role to grant to user or group
|
||||
scm.repo.set-role.forGroup = Set role for a group, not for a user
|
||||
|
||||
scm.repo.add-permissions.usage.description.0 = Add single permission for user or group
|
||||
scm.repo.add-permissions.usage.description.0 = Add single permissions for user or group
|
||||
scm.repo.add-permissions.repository = Repository namespace/name
|
||||
scm.repo.add-permissions.name = User or group name to grant permission to
|
||||
scm.repo.add-permissions.verbs = Single permissions to grant to user or group
|
||||
@@ -139,6 +139,27 @@ scm.repo.permissions.description = Description
|
||||
roleNotFound= Could not find permission role
|
||||
verbNotFound= Could not find single permission
|
||||
|
||||
## Namespace
|
||||
scm.namespace.usage.description.0 = Resource command for all namespace-related actions
|
||||
scm.namespace.list.usage.description.0 = List all namespaces on server
|
||||
|
||||
scm.namespace.available-permissions.usage.description.0 = List available permissions for namespace
|
||||
|
||||
scm.namespace.list-permissions.usage.description.0 = List permissions for namespace
|
||||
scm.namespace.list-permissions.namespace = Namespace
|
||||
|
||||
scm.namespace.add-permissions.usage.description.0 = Add single permissions for user or group
|
||||
scm.namespace.add-permissions.namespace = Namespace
|
||||
|
||||
scm.namespace.set-role.usage.description.0 = Set role permission for user or group
|
||||
scm.namespace.set-role.namespace = Namespace
|
||||
|
||||
scm.namespace.remove-permissions.usage.description.0 = Revoke single permission from user or group
|
||||
scm.namespace.remove-permissions.namespace = Namespace
|
||||
|
||||
scm.namespace.clear-permissions.usage.description.0 = Revoke all permissions from user or group
|
||||
scm.namespace.clear-permissions.namespace = Namespace
|
||||
|
||||
## User
|
||||
scm.user.username = Username
|
||||
scm.user.displayName = Display Name
|
||||
|
||||
@@ -109,7 +109,7 @@ scm.repo.set-role.name = Name des Benutzers oder der Gruppe f
|
||||
scm.repo.set-role.role = Rolle, die f<>r den Benutzer oder die Gruppe gesetzt werden soll
|
||||
scm.repo.set-role.forGroup = Setzt die Berechtigung f<>r eine Gruppe, nicht f<>r einen Benutzer
|
||||
|
||||
scm.repo.add-permissions.usage.description.0 = F<EFBFBD>gt eine einzelne Berechtigung f<>r einen Benutzer oder eine Gruppe hinzu
|
||||
scm.repo.add-permissions.usage.description.0 = F<EFBFBD>gt einzelne Berechtigungen f<>r einen Benutzer oder eine Gruppe hinzu
|
||||
scm.repo.add-permissions.repository = Repository Namespace/Name
|
||||
scm.repo.add-permissions.name = Name des Benutzers oder der Gruppe f<>r die Berechtigung
|
||||
scm.repo.add-permissions.verbs = Einzelne Berechtigungen, die f<>r den Benutzer oder die Gruppe hinzugef<65>gt werden sollen
|
||||
@@ -137,7 +137,28 @@ scm.repo.permissions.verb = Verb
|
||||
scm.repo.permissions.description = Beschreibung
|
||||
|
||||
roleNotFound= Berechtigungsrolle konnte nicht gefunden werden
|
||||
verbNotFound= konnte nicht gefunden werden
|
||||
verbNotFound= Berechtigung konnte nicht gefunden werden
|
||||
|
||||
## Namespace
|
||||
scm.namespace.usage.description.0 = Ressourcenkommando f<>r alle Aktionen zu Namespaces
|
||||
scm.namespace.list.usage.description.0 = Listet alle Namespaces
|
||||
|
||||
scm.namespace.available-permissions.usage.description.0 = Listet verf<72>gbare Berechtigungen f<>r den Namespace
|
||||
|
||||
scm.namespace.list-permissions.usage.description.0 = Listet die Berechtigungen f<>r den Namespace
|
||||
scm.namespace.list-permissions.namespace = Namespace
|
||||
|
||||
scm.namespace.add-permissions.usage.description.0 = F<EFBFBD>gt einzelne Berechtigungen f<>r einen Benutzer oder eine Gruppe hinzu
|
||||
scm.namespace.add-permissions.namespace = Namespace
|
||||
|
||||
scm.namespace.set-role.usage.description.0 = Setzt eine Berechtigungesrolle f<>r einen Benutzer oder eine Gruppe
|
||||
scm.namespace.set-role.namespace = Namespace
|
||||
|
||||
scm.namespace.remove-permissions.usage.description.0 = Entzieht einem Benutzer oder einer Gruppe einzelne Berechtigungen
|
||||
scm.namespace.remove-permissions.namespace = Namespace
|
||||
|
||||
scm.namespace.clear-permissions.usage.description.0 = Entzieht einem Benutzer oder einer Gruppe alle Berechtigungen
|
||||
scm.namespace.clear-permissions.namespace = Namespace
|
||||
|
||||
## User
|
||||
scm.user.username = Benutzername
|
||||
|
||||
@@ -0,0 +1,204 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020-present Cloudogu GmbH and Contributors
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package sonia.scm.repository.cli;
|
||||
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Nested;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Captor;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import sonia.scm.cli.CommandValidator;
|
||||
import sonia.scm.cli.PermissionDescriptionResolver;
|
||||
import sonia.scm.repository.Namespace;
|
||||
import sonia.scm.repository.NamespaceAndName;
|
||||
import sonia.scm.repository.NamespaceManager;
|
||||
import sonia.scm.repository.Repository;
|
||||
import sonia.scm.repository.RepositoryManager;
|
||||
import sonia.scm.repository.RepositoryPermission;
|
||||
import sonia.scm.repository.RepositoryRole;
|
||||
import sonia.scm.repository.RepositoryRoleManager;
|
||||
import sonia.scm.repository.RepositoryTestData;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import static java.util.Optional.of;
|
||||
import static java.util.stream.Collectors.toList;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.groups.Tuple.tuple;
|
||||
import static org.mockito.Mockito.doNothing;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class NamespacePermissionsListCommandTest {
|
||||
|
||||
@Mock
|
||||
private RepositoryTemplateRenderer templateRenderer;
|
||||
@Mock
|
||||
private CommandValidator validator;
|
||||
@Mock
|
||||
private NamespaceManager manager;
|
||||
@Mock
|
||||
private RepositoryRoleManager roleManager;
|
||||
@Mock
|
||||
private PermissionDescriptionResolver permissionDescriptionResolver;
|
||||
|
||||
@InjectMocks
|
||||
private RepositoryPermissionBeanMapper beanMapper;
|
||||
|
||||
private NamespacePermissionsListCommand command;
|
||||
|
||||
@BeforeEach
|
||||
void initCommand() {
|
||||
command = new NamespacePermissionsListCommand(templateRenderer, validator, manager, beanMapper);
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldPrintNotFoundErrorForUnknownRepository() {
|
||||
command.setNamespace("hg2g");
|
||||
|
||||
command.run();
|
||||
|
||||
verify(templateRenderer).renderNotFoundError();
|
||||
}
|
||||
|
||||
@Nested
|
||||
class ForExistingRepository {
|
||||
|
||||
@Captor
|
||||
private ArgumentCaptor<Collection<RepositoryPermissionBean>> permissionsCaptor;
|
||||
|
||||
private final Namespace namespace = new Namespace("hitchhiker");
|
||||
|
||||
@BeforeEach
|
||||
void mockRepository() {
|
||||
when(manager.get("hitchhiker"))
|
||||
.thenReturn(of(namespace));
|
||||
command.setNamespace("hitchhiker");
|
||||
}
|
||||
|
||||
@Nested
|
||||
class WithoutVerboseFlag {
|
||||
|
||||
@BeforeEach
|
||||
void setUpRenderer() {
|
||||
doNothing().when(templateRenderer).render(permissionsCaptor.capture());
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldRenderEmptyTableWithoutPermissions() {
|
||||
command.run();
|
||||
|
||||
Collection<RepositoryPermissionBean> beans = permissionsCaptor.getValue();
|
||||
assertThat(beans).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldListCustomUserPermission() {
|
||||
RepositoryPermission permission = new RepositoryPermission("trillian", List.of("read", "write"), false);
|
||||
namespace.setPermissions(List.of(permission));
|
||||
when(permissionDescriptionResolver.getDescription("read"))
|
||||
.thenReturn(of("read repository"));
|
||||
when(permissionDescriptionResolver.getDescription("write"))
|
||||
.thenReturn(of("write repository"));
|
||||
|
||||
command.run();
|
||||
|
||||
Collection<RepositoryPermissionBean> beans = permissionsCaptor.getValue();
|
||||
assertThat(beans).extracting("groupPermission", "name", "role")
|
||||
.containsExactly(tuple(false, "trillian", "CUSTOM"));
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
class WithVerboseFlag {
|
||||
|
||||
@BeforeEach
|
||||
void setUpRenderer() {
|
||||
doNothing().when(templateRenderer).renderVerbose(permissionsCaptor.capture());
|
||||
}
|
||||
|
||||
@BeforeEach
|
||||
void setVerbose() {
|
||||
command.setVerbose(true);
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldListUserPermissionWithVerbs() {
|
||||
RepositoryPermission permission = new RepositoryPermission("trillian", List.of("read", "write"), false);
|
||||
namespace.setPermissions(List.of(permission));
|
||||
when(permissionDescriptionResolver.getDescription("read"))
|
||||
.thenReturn(of("read repository"));
|
||||
when(permissionDescriptionResolver.getDescription("write"))
|
||||
.thenReturn(of("write repository"));
|
||||
|
||||
command.run();
|
||||
|
||||
Collection<RepositoryPermissionBean> beans = permissionsCaptor.getValue();
|
||||
assertThat(beans).extracting("groupPermission", "name", "role", "verbs")
|
||||
.containsExactly(tuple(false, "trillian", "CUSTOM", List.of("read repository", "write repository")));
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldListUserPermissionWithRole() {
|
||||
RepositoryPermission permission = new RepositoryPermission("trillian", "READ", false);
|
||||
namespace.setPermissions(List.of(permission));
|
||||
when(roleManager.get("READ"))
|
||||
.thenReturn(new RepositoryRole("READ", List.of("read", "pull"), ""));
|
||||
when(permissionDescriptionResolver.getDescription("read"))
|
||||
.thenReturn(of("read repository"));
|
||||
when(permissionDescriptionResolver.getDescription("pull"))
|
||||
.thenReturn(of("clone/checkout repository"));
|
||||
|
||||
command.run();
|
||||
|
||||
Collection<RepositoryPermissionBean> beans = permissionsCaptor.getValue();
|
||||
assertThat(beans).extracting("groupPermission", "name", "verbs")
|
||||
.containsExactly(tuple(false, "trillian", List.of("read repository", "clone/checkout repository")));
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldListUserPermissionWithVerbsAsKeys() {
|
||||
RepositoryPermission permission = new RepositoryPermission("trillian", List.of("read", "write"), false);
|
||||
namespace.setPermissions(List.of(permission));
|
||||
|
||||
command.setKeys(true);
|
||||
command.run();
|
||||
|
||||
Collection<RepositoryPermissionBean> beans = permissionsCaptor.getValue();
|
||||
assertThat(beans).extracting("groupPermission", "name", "role")
|
||||
.containsExactly(tuple(false, "trillian", "CUSTOM"));
|
||||
assertThat(beans).extracting("verbs")
|
||||
.map(c -> ((Collection) c).stream().collect(toList())) // to satisfy equal in the comparison, we have to use this form
|
||||
.containsExactly(List.of("read", "write"));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -43,7 +43,6 @@ import sonia.scm.repository.RepositoryTestData;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import static java.util.Optional.empty;
|
||||
import static java.util.Optional.of;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.groups.Tuple.tuple;
|
||||
@@ -91,7 +90,7 @@ class RepositoryPermissionsAddCommandTest {
|
||||
|
||||
@Test
|
||||
void shouldSetMultipleVerbsForNewUser() {
|
||||
command.setRepositoryName("hitchhiker/HeartOfGold");
|
||||
command.setRepositoryNamespaceAndName("hitchhiker/HeartOfGold");
|
||||
command.setName("trillian");
|
||||
command.setVerbs("read", "pull", "push");
|
||||
|
||||
@@ -112,7 +111,7 @@ class RepositoryPermissionsAddCommandTest {
|
||||
)
|
||||
);
|
||||
|
||||
command.setRepositoryName("hitchhiker/HeartOfGold");
|
||||
command.setRepositoryNamespaceAndName("hitchhiker/HeartOfGold");
|
||||
command.setName("trillian");
|
||||
command.setVerbs("write");
|
||||
|
||||
@@ -133,7 +132,7 @@ class RepositoryPermissionsAddCommandTest {
|
||||
)
|
||||
);
|
||||
|
||||
command.setRepositoryName("hitchhiker/HeartOfGold");
|
||||
command.setRepositoryNamespaceAndName("hitchhiker/HeartOfGold");
|
||||
command.setName("hog");
|
||||
command.setVerbs("write");
|
||||
command.setForGroup(true);
|
||||
@@ -157,7 +156,7 @@ class RepositoryPermissionsAddCommandTest {
|
||||
when(roleManager.get("READ"))
|
||||
.thenReturn(new RepositoryRole("READ", List.of("read", "pull"), ""));
|
||||
|
||||
command.setRepositoryName("hitchhiker/HeartOfGold");
|
||||
command.setRepositoryNamespaceAndName("hitchhiker/HeartOfGold");
|
||||
command.setName("trillian");
|
||||
command.setVerbs("write");
|
||||
|
||||
@@ -180,7 +179,7 @@ class RepositoryPermissionsAddCommandTest {
|
||||
when(roleManager.get("READ"))
|
||||
.thenReturn(new RepositoryRole("READ", List.of("read", "pull"), ""));
|
||||
|
||||
command.setRepositoryName("hitchhiker/HeartOfGold");
|
||||
command.setRepositoryNamespaceAndName("hitchhiker/HeartOfGold");
|
||||
command.setName("trillian");
|
||||
command.setVerbs("read");
|
||||
|
||||
@@ -192,19 +191,19 @@ class RepositoryPermissionsAddCommandTest {
|
||||
|
||||
@Test
|
||||
void shouldHandleMissingVerb() {
|
||||
command.setRepositoryName("hitchhiker/HeartOfGold");
|
||||
command.setRepositoryNamespaceAndName("hitchhiker/HeartOfGold");
|
||||
command.setName("trillian");
|
||||
command.setVerbs("make-party");
|
||||
|
||||
command.run();
|
||||
|
||||
verify(templateRenderer).renderVerbNotFoundError();
|
||||
verify(templateRenderer).renderVerbNotFoundError("make-party");
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldHandleIllegalNamespaceNameParameter() {
|
||||
command.setRepositoryName("illegal name");
|
||||
command.setRepositoryNamespaceAndName("illegal name");
|
||||
command.setName("trillian");
|
||||
command.setVerbs("write");
|
||||
|
||||
@@ -215,7 +214,7 @@ class RepositoryPermissionsAddCommandTest {
|
||||
|
||||
@Test
|
||||
void shouldHandleNotExistingRepository() {
|
||||
command.setRepositoryName("no/repository");
|
||||
command.setRepositoryNamespaceAndName("no/repository");
|
||||
command.setName("trillian");
|
||||
command.setVerbs("write");
|
||||
|
||||
|
||||
@@ -74,7 +74,7 @@ class RepositoryPermissionsClearCommandTest {
|
||||
)
|
||||
);
|
||||
|
||||
command.setRepositoryName("hitchhiker/HeartOfGold");
|
||||
command.setRepositoryNamespaceAndName("hitchhiker/HeartOfGold");
|
||||
command.setName("trillian");
|
||||
|
||||
command.run();
|
||||
@@ -93,7 +93,7 @@ class RepositoryPermissionsClearCommandTest {
|
||||
)
|
||||
);
|
||||
|
||||
command.setRepositoryName("hitchhiker/HeartOfGold");
|
||||
command.setRepositoryNamespaceAndName("hitchhiker/HeartOfGold");
|
||||
command.setName("hog");
|
||||
command.setForGroup(true);
|
||||
|
||||
@@ -108,7 +108,7 @@ class RepositoryPermissionsClearCommandTest {
|
||||
|
||||
@Test
|
||||
void shouldHandleIllegalNamespaceNameParameter() {
|
||||
command.setRepositoryName("illegal name");
|
||||
command.setRepositoryNamespaceAndName("illegal name");
|
||||
command.setName("trillian");
|
||||
|
||||
command.run();
|
||||
@@ -118,7 +118,7 @@ class RepositoryPermissionsClearCommandTest {
|
||||
|
||||
@Test
|
||||
void shouldHandleNotExistingRepository() {
|
||||
command.setRepositoryName("no/repository");
|
||||
command.setRepositoryNamespaceAndName("no/repository");
|
||||
command.setName("trillian");
|
||||
|
||||
command.run();
|
||||
|
||||
@@ -69,8 +69,15 @@ class RepositoryPermissionsListCommandTest {
|
||||
private PermissionDescriptionResolver permissionDescriptionResolver;
|
||||
|
||||
@InjectMocks
|
||||
private RepositoryPermissionBeanMapper beanMapper;
|
||||
|
||||
private RepositoryPermissionsListCommand command;
|
||||
|
||||
@BeforeEach
|
||||
void initCommand() {
|
||||
command = new RepositoryPermissionsListCommand(templateRenderer, validator, manager, beanMapper);
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldPrintNotFoundErrorForUnknownRepository() {
|
||||
command.setRepository("hg2g/hog");
|
||||
|
||||
@@ -82,7 +82,7 @@ class RepositoryPermissionsRemoveCommandTest {
|
||||
)
|
||||
);
|
||||
|
||||
command.setRepositoryName("hitchhiker/HeartOfGold");
|
||||
command.setRepositoryNamespaceAndName("hitchhiker/HeartOfGold");
|
||||
command.setName("dent");
|
||||
command.setVerbs("write", "push", "pull");
|
||||
|
||||
@@ -103,7 +103,7 @@ class RepositoryPermissionsRemoveCommandTest {
|
||||
)
|
||||
);
|
||||
|
||||
command.setRepositoryName("hitchhiker/HeartOfGold");
|
||||
command.setRepositoryNamespaceAndName("hitchhiker/HeartOfGold");
|
||||
command.setName("hog");
|
||||
command.setVerbs("write");
|
||||
command.setForGroup(true);
|
||||
@@ -127,7 +127,7 @@ class RepositoryPermissionsRemoveCommandTest {
|
||||
when(roleManager.get("READ"))
|
||||
.thenReturn(new RepositoryRole("READ", List.of("read", "pull"), ""));
|
||||
|
||||
command.setRepositoryName("hitchhiker/HeartOfGold");
|
||||
command.setRepositoryNamespaceAndName("hitchhiker/HeartOfGold");
|
||||
command.setName("dent");
|
||||
command.setVerbs("pull");
|
||||
|
||||
@@ -148,7 +148,7 @@ class RepositoryPermissionsRemoveCommandTest {
|
||||
)
|
||||
);
|
||||
|
||||
command.setRepositoryName("hitchhiker/HeartOfGold");
|
||||
command.setRepositoryNamespaceAndName("hitchhiker/HeartOfGold");
|
||||
command.setName("dent");
|
||||
command.setVerbs("push", "pull");
|
||||
|
||||
@@ -160,7 +160,7 @@ class RepositoryPermissionsRemoveCommandTest {
|
||||
|
||||
@Test
|
||||
void shouldHandleIllegalNamespaceNameParameter() {
|
||||
command.setRepositoryName("illegal name");
|
||||
command.setRepositoryNamespaceAndName("illegal name");
|
||||
command.setName("trillian");
|
||||
command.setVerbs("write");
|
||||
|
||||
@@ -171,7 +171,7 @@ class RepositoryPermissionsRemoveCommandTest {
|
||||
|
||||
@Test
|
||||
void shouldHandleNotExistingRepository() {
|
||||
command.setRepositoryName("no/repository");
|
||||
command.setRepositoryNamespaceAndName("no/repository");
|
||||
command.setName("trillian");
|
||||
command.setVerbs("write");
|
||||
|
||||
|
||||
@@ -85,7 +85,7 @@ class RepositoryPermissionsSetRoleCommandTest {
|
||||
|
||||
@Test
|
||||
void shouldSetRoleForUser() {
|
||||
command.setRepositoryName("hitchhiker/HeartOfGold");
|
||||
command.setRepositoryNamespaceAndName("hitchhiker/HeartOfGold");
|
||||
command.setName("trillian");
|
||||
command.setRole("OWNER");
|
||||
|
||||
@@ -100,7 +100,7 @@ class RepositoryPermissionsSetRoleCommandTest {
|
||||
|
||||
@Test
|
||||
void shouldSetRoleForGroup() {
|
||||
command.setRepositoryName("hitchhiker/HeartOfGold");
|
||||
command.setRepositoryNamespaceAndName("hitchhiker/HeartOfGold");
|
||||
command.setName("crew");
|
||||
command.setRole("READ");
|
||||
command.setForGroup(true);
|
||||
@@ -122,7 +122,7 @@ class RepositoryPermissionsSetRoleCommandTest {
|
||||
)
|
||||
);
|
||||
|
||||
command.setRepositoryName("hitchhiker/HeartOfGold");
|
||||
command.setRepositoryNamespaceAndName("hitchhiker/HeartOfGold");
|
||||
command.setName("trillian");
|
||||
command.setRole("OWNER");
|
||||
|
||||
@@ -143,7 +143,7 @@ class RepositoryPermissionsSetRoleCommandTest {
|
||||
)
|
||||
);
|
||||
|
||||
command.setRepositoryName("hitchhiker/HeartOfGold");
|
||||
command.setRepositoryNamespaceAndName("hitchhiker/HeartOfGold");
|
||||
command.setName("trillian");
|
||||
command.setRole("OWNER");
|
||||
command.setForGroup(true);
|
||||
@@ -160,7 +160,7 @@ class RepositoryPermissionsSetRoleCommandTest {
|
||||
|
||||
@Test
|
||||
void shouldHandleMissingRole() {
|
||||
command.setRepositoryName("hitchhiker/HeartOfGold");
|
||||
command.setRepositoryNamespaceAndName("hitchhiker/HeartOfGold");
|
||||
command.setName("trillian");
|
||||
command.setRole("FUNNY");
|
||||
|
||||
@@ -172,7 +172,7 @@ class RepositoryPermissionsSetRoleCommandTest {
|
||||
|
||||
@Test
|
||||
void shouldHandleIllegalNamespaceNameParameter() {
|
||||
command.setRepositoryName("illegal name");
|
||||
command.setRepositoryNamespaceAndName("illegal name");
|
||||
command.setName("trillian");
|
||||
command.setRole("READ");
|
||||
|
||||
@@ -184,7 +184,7 @@ class RepositoryPermissionsSetRoleCommandTest {
|
||||
|
||||
@Test
|
||||
void shouldHandleNotExistingRepository() {
|
||||
command.setRepositoryName("no/repository");
|
||||
command.setRepositoryNamespaceAndName("no/repository");
|
||||
command.setName("trillian");
|
||||
command.setRole("READ");
|
||||
|
||||
|
||||
Reference in New Issue
Block a user