mirror of
https://github.com/scm-manager/scm-manager.git
synced 2026-01-21 23:12:11 +01:00
Add cli commands for users and groups (#1993)
Adds cli commands to manage users and groups. Co-authored-by: Matthias Thieroff <matthias.thieroff@cloudogu.com>
This commit is contained in:
@@ -29,6 +29,7 @@ import picocli.AutoComplete;
|
||||
import picocli.CommandLine;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.util.Locale;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
public class CliProcessor {
|
||||
@@ -50,7 +51,7 @@ public class CliProcessor {
|
||||
CommandFactory factory = new CommandFactory(injector, context);
|
||||
CommandLine cli = new CommandLine(ScmManagerCommand.class, factory);
|
||||
cli.getCommandSpec().addMixin("help", usageHelp);
|
||||
cli.setResourceBundle(ResourceBundle.getBundle("sonia.scm.cli.i18n", context.getLocale()));
|
||||
cli.setResourceBundle(getBundle("sonia.scm.cli.i18n", context.getLocale()));
|
||||
for (RegisteredCommandNode c : registry.createCommandTree()) {
|
||||
CommandLine commandline = createCommandline(context, factory, c);
|
||||
cli.getCommandSpec().addSubcommand(c.getName(), commandline);
|
||||
@@ -69,7 +70,7 @@ public class CliProcessor {
|
||||
ResourceBundle resourceBundle = commandLine.getCommandSpec().resourceBundle();
|
||||
if (resourceBundle != null) {
|
||||
String resourceBundleBaseName = resourceBundle.getBaseBundleName();
|
||||
commandLine.setResourceBundle(ResourceBundle.getBundle(resourceBundleBaseName, context.getLocale()));
|
||||
commandLine.setResourceBundle(getBundle(resourceBundleBaseName, context.getLocale()));
|
||||
}
|
||||
for (RegisteredCommandNode child : command.getChildren()) {
|
||||
if (!commandLine.getCommandSpec().subcommands().containsKey(child.getName())) {
|
||||
@@ -80,4 +81,13 @@ public class CliProcessor {
|
||||
|
||||
return commandLine;
|
||||
}
|
||||
|
||||
private ResourceBundle getBundle(String baseName, Locale locale) {
|
||||
return ResourceBundle.getBundle(baseName, locale, new ResourceBundle.Control() {
|
||||
@Override
|
||||
public Locale getFallbackLocale(String baseName, Locale locale) {
|
||||
return Locale.ROOT;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* 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.group.cli;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import picocli.CommandLine;
|
||||
import sonia.scm.cli.ParentCommand;
|
||||
import sonia.scm.group.Group;
|
||||
import sonia.scm.group.GroupManager;
|
||||
import sonia.scm.repository.cli.GroupCommand;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.util.Arrays;
|
||||
|
||||
@ParentCommand(GroupCommand.class)
|
||||
@CommandLine.Command(name = "add-member", aliases = "add")
|
||||
class GroupAddMemberCommand implements Runnable {
|
||||
|
||||
@CommandLine.Mixin
|
||||
private final GroupTemplateRenderer templateRenderer;
|
||||
private final GroupManager manager;
|
||||
|
||||
@CommandLine.Parameters(index = "0", arity = "1", descriptionKey = "scm.group.add-member.name")
|
||||
private String name;
|
||||
@CommandLine.Parameters(index = "1..", arity = "1..", descriptionKey = "scm.group.add-member.members")
|
||||
private String[] members;
|
||||
|
||||
@Inject
|
||||
GroupAddMemberCommand(GroupTemplateRenderer templateRenderer, GroupManager manager) {
|
||||
this.templateRenderer = templateRenderer;
|
||||
this.manager = manager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
Group existingGroup = manager.get(name);
|
||||
if (existingGroup == null) {
|
||||
templateRenderer.renderNotFoundError();
|
||||
} else {
|
||||
Arrays.stream(members).forEach(existingGroup::add);
|
||||
manager.modify(existingGroup);
|
||||
Group modifiedGroup = manager.get(name);
|
||||
templateRenderer.render(modifiedGroup);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("SameParameterValue")
|
||||
@VisibleForTesting
|
||||
void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void setMembers(String[] members) {
|
||||
this.members = members;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* 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.group.cli;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
class GroupCommandBean {
|
||||
|
||||
private String name;
|
||||
private String description;
|
||||
private List<String> members;
|
||||
private String membersList;
|
||||
private boolean external;
|
||||
private String creationDate;
|
||||
private String lastModified;
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* 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.group.cli;
|
||||
|
||||
import org.mapstruct.AfterMapping;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.Mapping;
|
||||
import org.mapstruct.MappingTarget;
|
||||
import sonia.scm.group.Group;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
|
||||
@Mapper
|
||||
interface GroupCommandBeanMapper {
|
||||
|
||||
@Mapping(target = "membersList", ignore = true)
|
||||
GroupCommandBean map(Group group);
|
||||
|
||||
@AfterMapping
|
||||
default void mapMembersList(@MappingTarget GroupCommandBean bean) {
|
||||
if (bean.getMembers() != null) {
|
||||
bean.setMembersList(String.join(", ", bean.getMembers()));
|
||||
}
|
||||
}
|
||||
|
||||
default String mapTimestampToISODate(Long timestamp) {
|
||||
if (timestamp != null) {
|
||||
return DateTimeFormatter.ISO_INSTANT.format(Instant.ofEpochMilli(timestamp));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* 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.group.cli;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import picocli.CommandLine;
|
||||
import sonia.scm.cli.ParentCommand;
|
||||
import sonia.scm.group.Group;
|
||||
import sonia.scm.group.GroupManager;
|
||||
import sonia.scm.repository.cli.GroupCommand;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
@ParentCommand(GroupCommand.class)
|
||||
@CommandLine.Command(name = "create")
|
||||
class GroupCreateCommand implements Runnable {
|
||||
|
||||
@CommandLine.Mixin
|
||||
private final GroupTemplateRenderer templateRenderer;
|
||||
private final GroupManager manager;
|
||||
|
||||
@CommandLine.Parameters(descriptionKey = "scm.group.create.name")
|
||||
private String name;
|
||||
|
||||
@CommandLine.Option(names = {"--description", "-d"}, descriptionKey = "scm.group.create.desc")
|
||||
private String description;
|
||||
|
||||
@CommandLine.Option(names = {"--member", "-m"}, descriptionKey = "scm.group.create.member")
|
||||
private String[] members;
|
||||
|
||||
@CommandLine.Option(names = {"--external", "-e"}, descriptionKey = "scm.group.create.external")
|
||||
private boolean external;
|
||||
|
||||
@Inject
|
||||
GroupCreateCommand(GroupTemplateRenderer templateRenderer, GroupManager manager) {
|
||||
this.templateRenderer = templateRenderer;
|
||||
this.manager = manager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
Group newGroup = new Group("xml", name, members);
|
||||
newGroup.setDescription(description);
|
||||
newGroup.setExternal(external);
|
||||
Group createdGroup = manager.create(newGroup);
|
||||
templateRenderer.render(createdGroup);
|
||||
}
|
||||
|
||||
@SuppressWarnings("SameParameterValue")
|
||||
@VisibleForTesting
|
||||
void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@SuppressWarnings("SameParameterValue")
|
||||
@VisibleForTesting
|
||||
void setDescription(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void setMembers(String[] members) {
|
||||
this.members = members;
|
||||
}
|
||||
}
|
||||
@@ -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.group.cli;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import picocli.CommandLine;
|
||||
import sonia.scm.cli.ParentCommand;
|
||||
import sonia.scm.group.Group;
|
||||
import sonia.scm.group.GroupManager;
|
||||
import sonia.scm.repository.cli.GroupCommand;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.util.Collections;
|
||||
|
||||
@CommandLine.Command(name = "delete", aliases = "rm")
|
||||
@ParentCommand(GroupCommand.class)
|
||||
class GroupDeleteCommand implements Runnable {
|
||||
|
||||
private static final String PROMPT_TEMPLATE = "{{i18n.groupDeletePrompt}}";
|
||||
|
||||
@CommandLine.Parameters(descriptionKey = "scm.group.delete.group", paramLabel = "name")
|
||||
private String name;
|
||||
|
||||
@CommandLine.Option(names = {"--yes", "-y"}, descriptionKey = "scm.group.delete.prompt")
|
||||
private boolean shouldDelete;
|
||||
|
||||
@CommandLine.Mixin
|
||||
private final GroupTemplateRenderer templateRenderer;
|
||||
private final GroupManager manager;
|
||||
|
||||
@Inject
|
||||
GroupDeleteCommand(GroupTemplateRenderer templateRenderer, GroupManager manager) {
|
||||
this.templateRenderer = templateRenderer;
|
||||
this.manager = manager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
if (!shouldDelete) {
|
||||
templateRenderer.renderToStderr(PROMPT_TEMPLATE, Collections.emptyMap());
|
||||
return;
|
||||
}
|
||||
Group group = manager.get(name);
|
||||
if (group != null) {
|
||||
manager.delete(group);
|
||||
}
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void setShouldDelete(boolean shouldDelete) {
|
||||
this.shouldDelete = shouldDelete;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* 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.group.cli;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import picocli.CommandLine;
|
||||
import sonia.scm.cli.ParentCommand;
|
||||
import sonia.scm.group.Group;
|
||||
import sonia.scm.group.GroupManager;
|
||||
import sonia.scm.repository.cli.GroupCommand;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
@ParentCommand(GroupCommand.class)
|
||||
@CommandLine.Command(name = "get")
|
||||
class GroupGetCommand implements Runnable{
|
||||
|
||||
@CommandLine.Parameters(paramLabel = "name")
|
||||
private String name;
|
||||
|
||||
@CommandLine.Mixin
|
||||
private final GroupTemplateRenderer templateRenderer;
|
||||
private final GroupManager manager;
|
||||
|
||||
@Inject
|
||||
GroupGetCommand(GroupTemplateRenderer templateRenderer, GroupManager manager) {
|
||||
this.templateRenderer = templateRenderer;
|
||||
this.manager = manager;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
Group group = manager.get(name);
|
||||
if (group != null) {
|
||||
templateRenderer.render(group);
|
||||
} else {
|
||||
templateRenderer.renderNotFoundError();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
* 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.group.cli;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import picocli.CommandLine;
|
||||
import sonia.scm.cli.ParentCommand;
|
||||
import sonia.scm.cli.Table;
|
||||
import sonia.scm.cli.TemplateRenderer;
|
||||
import sonia.scm.group.GroupManager;
|
||||
import sonia.scm.repository.cli.GroupCommand;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.util.Collection;
|
||||
|
||||
import static java.util.stream.Collectors.toList;
|
||||
|
||||
@ParentCommand(GroupCommand.class)
|
||||
@CommandLine.Command(name = "list", aliases = "ls")
|
||||
class GroupListCommand implements Runnable {
|
||||
|
||||
@CommandLine.Mixin
|
||||
private final TemplateRenderer templateRenderer;
|
||||
private final GroupManager manager;
|
||||
private final GroupCommandBeanMapper beanMapper;
|
||||
@CommandLine.Spec
|
||||
private CommandLine.Model.CommandSpec spec;
|
||||
|
||||
@CommandLine.Option(names = {"--short", "-s"})
|
||||
private boolean useShortTemplate;
|
||||
|
||||
private static final String TABLE_TEMPLATE = String.join("\n",
|
||||
"{{#rows}}",
|
||||
"{{#cols}}{{#row.first}}{{#upper}}{{value}}{{/upper}}{{/row.first}}{{^row.first}}{{value}}{{/row.first}}{{^last}} {{/last}}{{/cols}}",
|
||||
"{{/rows}}"
|
||||
);
|
||||
|
||||
private static final String SHORT_TEMPLATE = String.join("\n",
|
||||
"{{#groups}}",
|
||||
"{{name}}",
|
||||
"{{/groups}}"
|
||||
);
|
||||
|
||||
@Inject
|
||||
GroupListCommand(TemplateRenderer templateRenderer, GroupManager manager, GroupCommandBeanMapper beanMapper) {
|
||||
this.templateRenderer = templateRenderer;
|
||||
this.manager = manager;
|
||||
this.beanMapper = beanMapper;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
Collection<GroupCommandBean> groupCommandBeans = manager.getAll().stream().map(beanMapper::map).collect(toList());
|
||||
if (useShortTemplate) {
|
||||
templateRenderer.renderToStdout(SHORT_TEMPLATE, ImmutableMap.of("groups", groupCommandBeans));
|
||||
} else {
|
||||
Table table = templateRenderer.createTable();
|
||||
table.addHeader("scm.group.name", "scm.group.external");
|
||||
String yes = spec.resourceBundle().getString("yes");
|
||||
String no = spec.resourceBundle().getString("no");
|
||||
for (GroupCommandBean bean : groupCommandBeans) {
|
||||
table.addRow(bean.getName(), bean.isExternal()? yes: no);
|
||||
}
|
||||
templateRenderer.renderToStdout(TABLE_TEMPLATE, ImmutableMap.of("rows", table, "groups", groupCommandBeans));
|
||||
}
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void setUseShortTemplate(boolean useShortTemplate) {
|
||||
this.useShortTemplate = useShortTemplate;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void setSpec(CommandLine.Model.CommandSpec spec) {
|
||||
this.spec = spec;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
/*
|
||||
* 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.group.cli;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import picocli.CommandLine;
|
||||
import sonia.scm.cli.ParentCommand;
|
||||
import sonia.scm.group.Group;
|
||||
import sonia.scm.group.GroupManager;
|
||||
import sonia.scm.repository.cli.GroupCommand;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import static java.util.Arrays.asList;
|
||||
|
||||
@ParentCommand(GroupCommand.class)
|
||||
@CommandLine.Command(name = "modify")
|
||||
class GroupModifyCommand implements Runnable {
|
||||
|
||||
@CommandLine.Mixin
|
||||
private final GroupTemplateRenderer templateRenderer;
|
||||
private final GroupManager manager;
|
||||
|
||||
@CommandLine.Parameters(descriptionKey = "scm.group.modify.name")
|
||||
private String name;
|
||||
|
||||
@CommandLine.Option(names = {"--description", "-d"}, descriptionKey = "scm.group.modify.desc")
|
||||
private String description;
|
||||
|
||||
@CommandLine.Option(names = {"--member", "-m"}, descriptionKey = "scm.group.modify.member")
|
||||
private String[] members;
|
||||
|
||||
@CommandLine.Option(names = {"--external", "-e"}, descriptionKey = "scm.group.modify.external")
|
||||
private Boolean external;
|
||||
|
||||
@Inject
|
||||
GroupModifyCommand(GroupTemplateRenderer templateRenderer, GroupManager manager) {
|
||||
this.templateRenderer = templateRenderer;
|
||||
this.manager = manager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
Group existingGroup = manager.get(name);
|
||||
if (existingGroup == null) {
|
||||
templateRenderer.renderNotFoundError();
|
||||
} else {
|
||||
if (description != null) {
|
||||
existingGroup.setDescription(description);
|
||||
}
|
||||
if (external != null) {
|
||||
existingGroup.setExternal(external);
|
||||
}
|
||||
if (members != null) {
|
||||
existingGroup.setMembers(asList(members));
|
||||
}
|
||||
manager.modify(existingGroup);
|
||||
Group modifiedGroup = manager.get(name);
|
||||
templateRenderer.render(modifiedGroup);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("SameParameterValue")
|
||||
@VisibleForTesting
|
||||
void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@SuppressWarnings("SameParameterValue")
|
||||
@VisibleForTesting
|
||||
void setDescription(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
@SuppressWarnings("SameParameterValue")
|
||||
@VisibleForTesting
|
||||
void setMembers(String[] members) {
|
||||
this.members = members;
|
||||
}
|
||||
|
||||
@SuppressWarnings("SameParameterValue")
|
||||
@VisibleForTesting
|
||||
void setExternal(boolean external) {
|
||||
this.external = external;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* 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.group.cli;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import picocli.CommandLine;
|
||||
import sonia.scm.cli.ParentCommand;
|
||||
import sonia.scm.group.Group;
|
||||
import sonia.scm.group.GroupManager;
|
||||
import sonia.scm.repository.cli.GroupCommand;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.util.Arrays;
|
||||
|
||||
@ParentCommand(GroupCommand.class)
|
||||
@CommandLine.Command(name = "remove-member", aliases = "remove")
|
||||
class GroupRemoveMemberCommand implements Runnable {
|
||||
|
||||
@CommandLine.Mixin
|
||||
private final GroupTemplateRenderer templateRenderer;
|
||||
private final GroupManager manager;
|
||||
|
||||
@CommandLine.Parameters(index = "0", arity = "1", descriptionKey = "scm.group.remove-member.name")
|
||||
private String name;
|
||||
@CommandLine.Parameters(index = "1..", arity = "1..", descriptionKey = "scm.group.remove-member.members")
|
||||
private String[] members;
|
||||
|
||||
@Inject
|
||||
GroupRemoveMemberCommand(GroupTemplateRenderer templateRenderer, GroupManager manager) {
|
||||
this.templateRenderer = templateRenderer;
|
||||
this.manager = manager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
Group existingGroup = manager.get(name);
|
||||
if (existingGroup == null) {
|
||||
templateRenderer.renderNotFoundError();
|
||||
} else {
|
||||
Arrays.stream(members).forEach(existingGroup::remove);
|
||||
manager.modify(existingGroup);
|
||||
Group modifiedGroup = manager.get(name);
|
||||
templateRenderer.render(modifiedGroup);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("SameParameterValue")
|
||||
@VisibleForTesting
|
||||
void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void setMembers(String[] members) {
|
||||
this.members = members;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* 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.group.cli;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import sonia.scm.cli.CliContext;
|
||||
import sonia.scm.cli.ExitCode;
|
||||
import sonia.scm.cli.Table;
|
||||
import sonia.scm.cli.TemplateRenderer;
|
||||
import sonia.scm.group.Group;
|
||||
import sonia.scm.template.TemplateEngineFactory;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.util.Collections;
|
||||
|
||||
class GroupTemplateRenderer extends TemplateRenderer {
|
||||
|
||||
private static final String NOT_FOUND_TEMPLATE = "{{i18n.groupNotFound}}";
|
||||
|
||||
private static final String DETAILS_TABLE_TEMPLATE = String.join("\n",
|
||||
"{{#rows}}",
|
||||
"{{#cols}}{{value}}{{/cols}}",
|
||||
"{{/rows}}"
|
||||
);
|
||||
|
||||
private final GroupCommandBeanMapper mapper;
|
||||
|
||||
@Inject
|
||||
GroupTemplateRenderer(CliContext context, TemplateEngineFactory templateEngineFactory, GroupCommandBeanMapper mapper) {
|
||||
super(context, templateEngineFactory);
|
||||
this.mapper = mapper;
|
||||
}
|
||||
|
||||
void render(Group group) {
|
||||
GroupCommandBean groupBean = mapper.map(group);
|
||||
Table table = createTable();
|
||||
String yes = getBundle().getString("yes");
|
||||
String no = getBundle().getString("no");
|
||||
table.addLabelValueRow("scm.group.name", groupBean.getName());
|
||||
table.addLabelValueRow("scm.group.description", groupBean.getDescription());
|
||||
table.addLabelValueRow("scm.group.members", groupBean.getMembersList());
|
||||
table.addLabelValueRow("scm.group.external", groupBean.isExternal() ? yes : no);
|
||||
table.addLabelValueRow("creationDate", groupBean.getCreationDate());
|
||||
table.addLabelValueRow("lastModified", groupBean.getLastModified());
|
||||
|
||||
renderToStdout(DETAILS_TABLE_TEMPLATE, ImmutableMap.of("rows", table, "repo", groupBean));
|
||||
}
|
||||
|
||||
void renderNotFoundError() {
|
||||
renderToStderr(NOT_FOUND_TEMPLATE, Collections.emptyMap());
|
||||
getContext().exit(ExitCode.NOT_FOUND);
|
||||
}
|
||||
}
|
||||
@@ -51,7 +51,7 @@ class RepositoryGetCommand implements Runnable {
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
public void setRepository(String repository) {
|
||||
void setRepository(String repository) {
|
||||
this.repository = repository;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* 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.user.cli;
|
||||
|
||||
import picocli.CommandLine;
|
||||
import sonia.scm.cli.ParentCommand;
|
||||
import sonia.scm.user.User;
|
||||
import sonia.scm.user.UserManager;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
@ParentCommand(value = UserCommand.class)
|
||||
@CommandLine.Command(name = "activate")
|
||||
class UserActivateCommand implements Runnable {
|
||||
|
||||
@CommandLine.Mixin
|
||||
private final UserTemplateRenderer templateRenderer;
|
||||
private final UserManager manager;
|
||||
|
||||
@CommandLine.Parameters(index = "0", paramLabel = "<username>", descriptionKey = "scm.user.username")
|
||||
private String username;
|
||||
|
||||
@Inject
|
||||
UserActivateCommand(UserTemplateRenderer templateRenderer, UserManager manager) {
|
||||
this.templateRenderer = templateRenderer;
|
||||
this.manager = manager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
User user = manager.get(username);
|
||||
|
||||
if (user != null) {
|
||||
if (user.isExternal()) {
|
||||
templateRenderer.renderExternalActivateError();
|
||||
} else {
|
||||
user.setActive(true);
|
||||
manager.modify(user);
|
||||
templateRenderer.render(user);
|
||||
}
|
||||
} else {
|
||||
templateRenderer.renderNotFoundError();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* 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.user.cli;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@NoArgsConstructor
|
||||
class UserCommandBean {
|
||||
|
||||
private String name;
|
||||
private String displayName;
|
||||
private String mail;
|
||||
private boolean external;
|
||||
private boolean active;
|
||||
private String creationDate;
|
||||
private String lastModified;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* 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.user.cli;
|
||||
|
||||
import org.mapstruct.Mapper;
|
||||
import sonia.scm.user.User;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
|
||||
@Mapper
|
||||
interface UserCommandBeanMapper {
|
||||
|
||||
UserCommandBean map(User modelObject);
|
||||
|
||||
default String mapTimestampToISODate(Long timestamp) {
|
||||
if (timestamp != null) {
|
||||
return DateTimeFormatter.ISO_INSTANT.format(Instant.ofEpochMilli(timestamp));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* 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.user.cli;
|
||||
|
||||
import picocli.CommandLine;
|
||||
import sonia.scm.cli.ParentCommand;
|
||||
import sonia.scm.user.User;
|
||||
import sonia.scm.user.UserManager;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
@ParentCommand(value = UserCommand.class)
|
||||
@CommandLine.Command(name = "convert-to-external", aliases = "conv-ext")
|
||||
class UserConvertToExternalCommand implements Runnable {
|
||||
|
||||
@CommandLine.Mixin
|
||||
private final UserTemplateRenderer templateRenderer;
|
||||
private final UserManager manager;
|
||||
|
||||
@CommandLine.Parameters(index = "0", paramLabel = "<username>", descriptionKey = "scm.user.username")
|
||||
private String username;
|
||||
|
||||
@Inject
|
||||
UserConvertToExternalCommand(UserTemplateRenderer templateRenderer, UserManager manager) {
|
||||
this.templateRenderer = templateRenderer;
|
||||
this.manager = manager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
User user = manager.get(username);
|
||||
|
||||
if (user != null) {
|
||||
user.setExternal(true);
|
||||
manager.modify(user);
|
||||
templateRenderer.render(user);
|
||||
} else {
|
||||
templateRenderer.renderNotFoundError();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* 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.user.cli;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import picocli.CommandLine;
|
||||
import sonia.scm.cli.ParentCommand;
|
||||
import sonia.scm.user.User;
|
||||
import sonia.scm.user.UserManager;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
@ParentCommand(value = UserCommand.class)
|
||||
@CommandLine.Command(name = "convert-to-internal", aliases = "conv-int")
|
||||
class UserConvertToInternalCommand implements Runnable {
|
||||
|
||||
@CommandLine.Mixin
|
||||
private final UserTemplateRenderer templateRenderer;
|
||||
private final UserManager manager;
|
||||
|
||||
@CommandLine.Parameters(index = "0", paramLabel = "<username>", descriptionKey = "scm.user.username")
|
||||
private String username;
|
||||
|
||||
@CommandLine.Parameters(index = "1", paramLabel = "<password>", descriptionKey = "scm.user.password")
|
||||
private String password;
|
||||
|
||||
@Inject
|
||||
UserConvertToInternalCommand(UserTemplateRenderer templateRenderer, UserManager manager) {
|
||||
this.templateRenderer = templateRenderer;
|
||||
this.manager = manager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
User user = manager.get(username);
|
||||
|
||||
if (user != null) {
|
||||
user.setExternal(false);
|
||||
user.setPassword(password);
|
||||
manager.modify(user);
|
||||
templateRenderer.render(user);
|
||||
} else {
|
||||
templateRenderer.renderNotFoundError();
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("SameParameterValue")
|
||||
@VisibleForTesting
|
||||
void setPassword(String password) {
|
||||
this.password = password;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,133 @@
|
||||
/*
|
||||
* 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.user.cli;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import picocli.CommandLine;
|
||||
import sonia.scm.cli.CommandValidator;
|
||||
import sonia.scm.cli.ParentCommand;
|
||||
import sonia.scm.user.User;
|
||||
import sonia.scm.user.UserManager;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.validation.constraints.Email;
|
||||
|
||||
@CommandLine.Command(name = "create")
|
||||
@ParentCommand(value = UserCommand.class)
|
||||
class UserCreateCommand implements Runnable {
|
||||
|
||||
@CommandLine.Mixin
|
||||
private final UserTemplateRenderer templateRenderer;
|
||||
@CommandLine.Mixin
|
||||
private final CommandValidator validator;
|
||||
private final UserManager manager;
|
||||
|
||||
@CommandLine.Parameters(index = "0", paramLabel = "<username>", descriptionKey = "scm.user.username")
|
||||
private String username;
|
||||
|
||||
@CommandLine.Parameters(index = "1", paramLabel = "<displayname>", descriptionKey = "scm.user.displayName")
|
||||
private String displayName;
|
||||
|
||||
@Email
|
||||
@CommandLine.Option(names = {"--email", "-e"}, descriptionKey = "scm.user.email")
|
||||
private String email;
|
||||
|
||||
@CommandLine.Option(names = {"--external", "-x"}, descriptionKey = "scm.user.create.external")
|
||||
private boolean external;
|
||||
|
||||
@CommandLine.Option(names = {"--password", "-p"}, descriptionKey = "scm.user.password")
|
||||
private String password;
|
||||
|
||||
@CommandLine.Option(names = {"--deactivate", "-d"}, descriptionKey = "scm.user.create.deactivate")
|
||||
private boolean inactive;
|
||||
|
||||
@Inject
|
||||
public UserCreateCommand(UserTemplateRenderer templateRenderer,
|
||||
CommandValidator validator,
|
||||
UserManager manager) {
|
||||
this.templateRenderer = templateRenderer;
|
||||
this.validator = validator;
|
||||
this.manager = manager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
validator.validate();
|
||||
User newUser = new User();
|
||||
newUser.setName(username);
|
||||
newUser.setDisplayName(displayName);
|
||||
newUser.setMail(email);
|
||||
newUser.setExternal(external);
|
||||
if (!external) {
|
||||
if (password == null) {
|
||||
templateRenderer.renderPasswordError();
|
||||
}
|
||||
newUser.setPassword(password);
|
||||
newUser.setActive(!inactive);
|
||||
} else {
|
||||
if (inactive) {
|
||||
templateRenderer.renderExternalDeactivateError();
|
||||
}
|
||||
}
|
||||
User createdUser = manager.create(newUser);
|
||||
templateRenderer.render(createdUser);
|
||||
}
|
||||
|
||||
@SuppressWarnings("SameParameterValue")
|
||||
@VisibleForTesting
|
||||
void setUsername(String username) {
|
||||
this.username = username;
|
||||
}
|
||||
|
||||
@SuppressWarnings("SameParameterValue")
|
||||
@VisibleForTesting
|
||||
void setDisplayName(String displayName) {
|
||||
this.displayName = displayName;
|
||||
}
|
||||
|
||||
@SuppressWarnings("SameParameterValue")
|
||||
@VisibleForTesting
|
||||
void setEmail(String email) {
|
||||
this.email = email;
|
||||
}
|
||||
|
||||
@SuppressWarnings("SameParameterValue")
|
||||
@VisibleForTesting
|
||||
void setExternal(boolean external) {
|
||||
this.external = external;
|
||||
}
|
||||
|
||||
@SuppressWarnings("SameParameterValue")
|
||||
@VisibleForTesting
|
||||
void setPassword(String password) {
|
||||
this.password = password;
|
||||
}
|
||||
|
||||
@SuppressWarnings("SameParameterValue")
|
||||
@VisibleForTesting
|
||||
void setInactive(boolean inactive) {
|
||||
this.inactive = inactive;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* 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.user.cli;
|
||||
|
||||
import picocli.CommandLine;
|
||||
import sonia.scm.cli.ParentCommand;
|
||||
import sonia.scm.user.User;
|
||||
import sonia.scm.user.UserManager;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
@ParentCommand(value = UserCommand.class)
|
||||
@CommandLine.Command(name = "deactivate")
|
||||
class UserDeactivateCommand implements Runnable {
|
||||
|
||||
@CommandLine.Mixin
|
||||
private final UserTemplateRenderer templateRenderer;
|
||||
private final UserManager manager;
|
||||
|
||||
@CommandLine.Parameters(index = "0", paramLabel = "<username>", descriptionKey = "scm.user.username")
|
||||
private String username;
|
||||
|
||||
@Inject
|
||||
UserDeactivateCommand(UserTemplateRenderer templateRenderer, UserManager manager) {
|
||||
this.templateRenderer = templateRenderer;
|
||||
this.manager = manager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
User user = manager.get(username);
|
||||
|
||||
if (user != null) {
|
||||
if (user.isExternal()) {
|
||||
templateRenderer.renderExternalDeactivateError();
|
||||
} else {
|
||||
user.setActive(false);
|
||||
manager.modify(user);
|
||||
templateRenderer.render(user);
|
||||
}
|
||||
} else {
|
||||
templateRenderer.renderNotFoundError();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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.user.cli;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import picocli.CommandLine;
|
||||
import sonia.scm.cli.ParentCommand;
|
||||
import sonia.scm.user.User;
|
||||
import sonia.scm.user.UserManager;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.util.Collections;
|
||||
|
||||
@CommandLine.Command(name = "delete", aliases = "rm")
|
||||
@ParentCommand(UserCommand.class)
|
||||
class UserDeleteCommand implements Runnable {
|
||||
|
||||
private static final String CONFIRM_TEMPLATE = "{{i18n.scmUserDeleteConfirm}}";
|
||||
private static final String SUCCESS_TEMPLATE = "{{i18n.scmUserDeleteSuccess}}";
|
||||
|
||||
@CommandLine.Parameters(index = "0", paramLabel = "<username>", descriptionKey = "scm.user.username")
|
||||
private String username;
|
||||
|
||||
@CommandLine.Option(names = {"--yes", "-y"}, descriptionKey = "scm.user.delete.prompt")
|
||||
private boolean shouldDelete;
|
||||
|
||||
@CommandLine.Mixin
|
||||
private final UserTemplateRenderer templateRenderer;
|
||||
private final UserManager manager;
|
||||
|
||||
@Inject
|
||||
public UserDeleteCommand(UserTemplateRenderer templateRenderer, UserManager manager) {
|
||||
this.templateRenderer = templateRenderer;
|
||||
this.manager = manager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
if (!shouldDelete) {
|
||||
templateRenderer.renderToStderr(CONFIRM_TEMPLATE, Collections.emptyMap());
|
||||
return;
|
||||
}
|
||||
User user = manager.get(username);
|
||||
if (user != null) {
|
||||
manager.delete(user);
|
||||
templateRenderer.renderToStdout(SUCCESS_TEMPLATE, Collections.emptyMap());
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("SameParameterValue")
|
||||
@VisibleForTesting
|
||||
void setShouldDelete(boolean shouldDelete) {
|
||||
this.shouldDelete = shouldDelete;
|
||||
}
|
||||
}
|
||||
@@ -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.user.cli;
|
||||
|
||||
import picocli.CommandLine;
|
||||
import sonia.scm.cli.ParentCommand;
|
||||
import sonia.scm.user.User;
|
||||
import sonia.scm.user.UserManager;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
@ParentCommand(value = UserCommand.class)
|
||||
@CommandLine.Command(name = "get")
|
||||
class UserGetCommand implements Runnable {
|
||||
|
||||
@CommandLine.Parameters(index = "0", paramLabel = "<username>", descriptionKey = "scm.user.username")
|
||||
private String username;
|
||||
|
||||
@CommandLine.Mixin
|
||||
private final UserTemplateRenderer templateRenderer;
|
||||
private final UserManager manager;
|
||||
|
||||
@Inject
|
||||
UserGetCommand(UserTemplateRenderer templateRenderer, UserManager manager) {
|
||||
this.templateRenderer = templateRenderer;
|
||||
this.manager = manager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
User user = manager.get(username);
|
||||
if (user != null) {
|
||||
templateRenderer.render(user);
|
||||
} else {
|
||||
templateRenderer.renderNotFoundError();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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.user.cli;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import picocli.CommandLine;
|
||||
import sonia.scm.cli.ParentCommand;
|
||||
import sonia.scm.cli.Table;
|
||||
import sonia.scm.cli.TemplateRenderer;
|
||||
import sonia.scm.user.UserManager;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.util.Collection;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@ParentCommand(value = UserCommand.class)
|
||||
@CommandLine.Command(name = "list", aliases = "ls")
|
||||
class UserListCommand implements Runnable {
|
||||
|
||||
@CommandLine.Mixin
|
||||
private final TemplateRenderer templateRenderer;
|
||||
private final UserManager manager;
|
||||
private final UserCommandBeanMapper mapper;
|
||||
@CommandLine.Spec
|
||||
private CommandLine.Model.CommandSpec spec;
|
||||
|
||||
@CommandLine.Option(names = {"--short", "-s"})
|
||||
private boolean useShortTemplate;
|
||||
|
||||
private static final String TABLE_TEMPLATE = String.join("\n",
|
||||
"{{#rows}}",
|
||||
"{{#cols}}{{#row.first}}{{#upper}}{{value}}{{/upper}}{{/row.first}}{{^row.first}}{{value}}{{/row.first}}{{^last}} {{/last}}{{/cols}}",
|
||||
"{{/rows}}"
|
||||
);
|
||||
|
||||
private static final String SHORT_TEMPLATE = String.join("\n",
|
||||
"{{#users}}",
|
||||
"{{name}}",
|
||||
"{{/users}}"
|
||||
);
|
||||
|
||||
@Inject
|
||||
public UserListCommand(TemplateRenderer templateRenderer, UserManager manager, UserCommandBeanMapper mapper) {
|
||||
this.templateRenderer = templateRenderer;
|
||||
this.manager = manager;
|
||||
this.mapper = mapper;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
Collection<UserCommandBean> beans = manager.getAll().stream().map(mapper::map).collect(Collectors.toList());
|
||||
if (useShortTemplate) {
|
||||
templateRenderer.renderToStdout(SHORT_TEMPLATE, ImmutableMap.of("users", beans));
|
||||
} else {
|
||||
Table table = templateRenderer.createTable();
|
||||
String yes = spec.resourceBundle().getString("yes");
|
||||
String no = spec.resourceBundle().getString("no");
|
||||
table.addHeader("scm.user.username", "scm.user.displayName", "scm.user.email", "scm.user.external", "scm.user.active");
|
||||
for (UserCommandBean bean : beans) {
|
||||
table.addRow(bean.getName(), bean.getDisplayName(), bean.getMail(), bean.isExternal() ? yes : no, bean.isActive() ? yes : no);
|
||||
}
|
||||
templateRenderer.renderToStdout(TABLE_TEMPLATE, ImmutableMap.of("rows", table, "users", beans));
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("SameParameterValue")
|
||||
@VisibleForTesting
|
||||
void setUseShortTemplate(boolean useShortTemplate) {
|
||||
this.useShortTemplate = useShortTemplate;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void setSpec(CommandLine.Model.CommandSpec spec) {
|
||||
this.spec = spec;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
/*
|
||||
* 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.user.cli;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import picocli.CommandLine;
|
||||
import sonia.scm.cli.CommandValidator;
|
||||
import sonia.scm.cli.ParentCommand;
|
||||
import sonia.scm.user.User;
|
||||
import sonia.scm.user.UserManager;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.validation.constraints.Email;
|
||||
|
||||
@ParentCommand(value = UserCommand.class)
|
||||
@CommandLine.Command(name = "modify")
|
||||
class UserModifyCommand implements Runnable {
|
||||
|
||||
@CommandLine.Mixin
|
||||
private final UserTemplateRenderer templateRenderer;
|
||||
@CommandLine.Mixin
|
||||
private final CommandValidator validator;
|
||||
private final UserManager manager;
|
||||
|
||||
@CommandLine.Parameters(index = "0", paramLabel = "<username>", descriptionKey = "scm.user.username")
|
||||
private String username;
|
||||
|
||||
@CommandLine.Option(names = {"--displayname", "-d"}, descriptionKey = "scm.user.displayName")
|
||||
private String displayName;
|
||||
|
||||
@Email
|
||||
@CommandLine.Option(names = {"--email", "-e"}, descriptionKey = "scm.user.email")
|
||||
private String email;
|
||||
|
||||
@CommandLine.Option(names = {"--password", "-p"}, descriptionKey = "scm.user.password")
|
||||
private String password;
|
||||
|
||||
@Inject
|
||||
UserModifyCommand(UserTemplateRenderer templateRenderer, CommandValidator validator, UserManager manager) {
|
||||
this.templateRenderer = templateRenderer;
|
||||
this.validator = validator;
|
||||
this.manager = manager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
validator.validate();
|
||||
|
||||
User user = manager.get(username);
|
||||
|
||||
if (user != null) {
|
||||
if (displayName != null) {
|
||||
user.setDisplayName(displayName);
|
||||
}
|
||||
if (email != null) {
|
||||
user.setMail(email);
|
||||
}
|
||||
if (password != null) {
|
||||
user.setPassword(password);
|
||||
}
|
||||
manager.modify(user);
|
||||
templateRenderer.render(user);
|
||||
} else {
|
||||
templateRenderer.renderNotFoundError();
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("SameParameterValue")
|
||||
@VisibleForTesting
|
||||
void setDisplayName(String displayName) {
|
||||
this.displayName = displayName;
|
||||
}
|
||||
|
||||
@SuppressWarnings("SameParameterValue")
|
||||
@VisibleForTesting
|
||||
void setEmail(String email) {
|
||||
this.email = email;
|
||||
}
|
||||
|
||||
@SuppressWarnings("SameParameterValue")
|
||||
@VisibleForTesting
|
||||
void setPassword(String password) {
|
||||
this.password = password;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* 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.user.cli;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import sonia.scm.cli.CliContext;
|
||||
import sonia.scm.cli.ExitCode;
|
||||
import sonia.scm.cli.Table;
|
||||
import sonia.scm.cli.TemplateRenderer;
|
||||
import sonia.scm.template.TemplateEngineFactory;
|
||||
import sonia.scm.user.User;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.util.Collections;
|
||||
|
||||
class UserTemplateRenderer extends TemplateRenderer {
|
||||
|
||||
private static final String DETAILS_TABLE_TEMPLATE = String.join("\n",
|
||||
"{{#rows}}",
|
||||
"{{#cols}}{{value}}{{/cols}}",
|
||||
"{{/rows}}"
|
||||
);
|
||||
private static final String PASSWORD_ERROR_TEMPLATE = "{{i18n.scmUserErrorPassword}}";
|
||||
private static final String EXTERNAL_ACTIVATE_TEMPLATE = "{{i18n.scmUserErrorExternalActivate}}";
|
||||
private static final String EXTERNAL_DEACTIVATE_TEMPLATE = "{{i18n.scmUserErrorExternalDeactivate}}";
|
||||
private static final String NOT_FOUND_TEMPLATE = "{{i18n.scmUserErrorNotFound}}";
|
||||
|
||||
private final CliContext context;
|
||||
private final UserCommandBeanMapper mapper;
|
||||
|
||||
@Inject
|
||||
UserTemplateRenderer(CliContext context, TemplateEngineFactory templateEngineFactory, UserCommandBeanMapper mapper) {
|
||||
super(context, templateEngineFactory);
|
||||
this.context = context;
|
||||
this.mapper = mapper;
|
||||
}
|
||||
|
||||
public void render(User user) {
|
||||
Table table = createTable();
|
||||
|
||||
String yes = getBundle().getString("yes");
|
||||
String no = getBundle().getString("no");
|
||||
UserCommandBean bean = mapper.map(user);
|
||||
table.addLabelValueRow("scm.user.username", bean.getName());
|
||||
table.addLabelValueRow("scm.user.displayName", bean.getDisplayName());
|
||||
table.addLabelValueRow("scm.user.email", bean.getMail());
|
||||
table.addLabelValueRow("scm.user.external", bean.isExternal() ? yes : no);
|
||||
table.addLabelValueRow("scm.user.active", bean.isActive() ? yes : no);
|
||||
table.addLabelValueRow("creationDate", bean.getCreationDate());
|
||||
table.addLabelValueRow("lastModified", bean.getLastModified());
|
||||
renderToStdout(DETAILS_TABLE_TEMPLATE, ImmutableMap.of("rows", table, "user", bean));
|
||||
}
|
||||
|
||||
public void renderPasswordError() {
|
||||
renderToStderr(PASSWORD_ERROR_TEMPLATE, Collections.emptyMap());
|
||||
context.exit(ExitCode.USAGE);
|
||||
}
|
||||
|
||||
public void renderExternalActivateError() {
|
||||
renderToStderr(EXTERNAL_ACTIVATE_TEMPLATE, Collections.emptyMap());
|
||||
context.exit(ExitCode.USAGE);
|
||||
}
|
||||
|
||||
public void renderExternalDeactivateError() {
|
||||
renderToStderr(EXTERNAL_DEACTIVATE_TEMPLATE, Collections.emptyMap());
|
||||
context.exit(ExitCode.USAGE);
|
||||
}
|
||||
|
||||
public void renderNotFoundError() {
|
||||
renderToStderr(NOT_FOUND_TEMPLATE, Collections.emptyMap());
|
||||
context.exit(ExitCode.NOT_FOUND);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user