From 818622acc3050ea9289a45739ef6dffc9832073e Mon Sep 17 00:00:00 2001 From: kadraman Date: Fri, 3 Feb 2023 10:11:39 +0000 Subject: [PATCH] feat: FoD: Added functionality for user CRUD (implements #245) feat: FoD: Added functionality for user group CRUD (implements #246) --- .../cli/fod/_main/cli/cmd/FoDCommands.java | 6 +- .../fod/app/cli/cmd/FoDAppCreateCommand.java | 5 +- .../cli/fod/app/helper/FoDAppHelper.java | 31 ++-- .../com/fortify/cli/fod/rest/FoDUrls.java | 9 +- .../cli/fod/user/cli/cmd/FoDUserCommands.java | 42 +++++ .../user/cli/cmd/FoDUserCreateCommand.java | 110 +++++++++++++ .../user/cli/cmd/FoDUserDeleteCommand.java | 72 +++++++++ .../fod/user/cli/cmd/FoDUserGetCommand.java | 61 +++++++ .../fod/user/cli/cmd/FoDUserListCommand.java | 69 ++++++++ .../user/cli/cmd/FoDUserUpdateCommand.java | 140 ++++++++++++++++ .../user/cli/mixin/FoDUserResolverMixin.java | 74 +++++++++ .../user/helper/FoDUserAppAccessRequest.java | 42 +++++ .../fod/user/helper/FoDUserCreateRequest.java | 97 +++++++++++ .../fod/user/helper/FoDUserDescriptor.java | 1 - .../cli/fod/user/helper/FoDUserHelper.java | 147 ++++++++++++++++- .../fod/user/helper/FoDUserUpdateRequest.java | 115 +++++++++++++ .../cli/cmd/FoDUserGroupCommands.java | 42 +++++ .../cli/cmd/FoDUserGroupCreateCommand.java | 93 +++++++++++ .../cli/cmd/FoDUserGroupDeleteCommand.java | 72 +++++++++ .../cli/cmd/FoDUserGroupGetCommand.java | 61 +++++++ .../cli/cmd/FoDUserGroupListCommand.java | 67 ++++++++ .../cli/cmd/FoDUserGroupUpdateCommand.java | 116 +++++++++++++ .../cli/mixin/FoDUserGroupResolverMixin.java | 74 +++++++++ .../helper/FoDUserGroupAppAccessRequest.java | 42 +++++ .../helper/FoDUserGroupCreateRequest.java | 62 +++++++ .../helper/FoDUserGroupDescriptor.java | 3 +- .../user_group/helper/FoDUserGroupHelper.java | 153 +++++++++++++++++- .../helper/FoDUserGroupMembersRequest.java | 50 ++++++ .../helper/FoDUserGroupUpdateRequest.java | 80 +++++++++ .../com/fortify/cli/fod/util/FoDEnums.java | 16 ++ .../cli/fod/i18n/FoDMessages.properties | 90 ++++++++++- 31 files changed, 2009 insertions(+), 33 deletions(-) create mode 100644 fcli-fod/src/main/java/com/fortify/cli/fod/user/cli/cmd/FoDUserCommands.java create mode 100644 fcli-fod/src/main/java/com/fortify/cli/fod/user/cli/cmd/FoDUserCreateCommand.java create mode 100644 fcli-fod/src/main/java/com/fortify/cli/fod/user/cli/cmd/FoDUserDeleteCommand.java create mode 100644 fcli-fod/src/main/java/com/fortify/cli/fod/user/cli/cmd/FoDUserGetCommand.java create mode 100644 fcli-fod/src/main/java/com/fortify/cli/fod/user/cli/cmd/FoDUserListCommand.java create mode 100644 fcli-fod/src/main/java/com/fortify/cli/fod/user/cli/cmd/FoDUserUpdateCommand.java create mode 100644 fcli-fod/src/main/java/com/fortify/cli/fod/user/cli/mixin/FoDUserResolverMixin.java create mode 100644 fcli-fod/src/main/java/com/fortify/cli/fod/user/helper/FoDUserAppAccessRequest.java create mode 100644 fcli-fod/src/main/java/com/fortify/cli/fod/user/helper/FoDUserCreateRequest.java create mode 100644 fcli-fod/src/main/java/com/fortify/cli/fod/user/helper/FoDUserUpdateRequest.java create mode 100644 fcli-fod/src/main/java/com/fortify/cli/fod/user_group/cli/cmd/FoDUserGroupCommands.java create mode 100644 fcli-fod/src/main/java/com/fortify/cli/fod/user_group/cli/cmd/FoDUserGroupCreateCommand.java create mode 100644 fcli-fod/src/main/java/com/fortify/cli/fod/user_group/cli/cmd/FoDUserGroupDeleteCommand.java create mode 100644 fcli-fod/src/main/java/com/fortify/cli/fod/user_group/cli/cmd/FoDUserGroupGetCommand.java create mode 100644 fcli-fod/src/main/java/com/fortify/cli/fod/user_group/cli/cmd/FoDUserGroupListCommand.java create mode 100644 fcli-fod/src/main/java/com/fortify/cli/fod/user_group/cli/cmd/FoDUserGroupUpdateCommand.java create mode 100644 fcli-fod/src/main/java/com/fortify/cli/fod/user_group/cli/mixin/FoDUserGroupResolverMixin.java create mode 100644 fcli-fod/src/main/java/com/fortify/cli/fod/user_group/helper/FoDUserGroupAppAccessRequest.java create mode 100644 fcli-fod/src/main/java/com/fortify/cli/fod/user_group/helper/FoDUserGroupCreateRequest.java create mode 100644 fcli-fod/src/main/java/com/fortify/cli/fod/user_group/helper/FoDUserGroupMembersRequest.java create mode 100644 fcli-fod/src/main/java/com/fortify/cli/fod/user_group/helper/FoDUserGroupUpdateRequest.java diff --git a/fcli-fod/src/main/java/com/fortify/cli/fod/_main/cli/cmd/FoDCommands.java b/fcli-fod/src/main/java/com/fortify/cli/fod/_main/cli/cmd/FoDCommands.java index 7f86cad2f2..ecb3e72bf4 100644 --- a/fcli-fod/src/main/java/com/fortify/cli/fod/_main/cli/cmd/FoDCommands.java +++ b/fcli-fod/src/main/java/com/fortify/cli/fod/_main/cli/cmd/FoDCommands.java @@ -11,6 +11,8 @@ import com.fortify.cli.fod.sast_scan.cli.cmd.FoDSastScanCommands; import com.fortify.cli.fod.scan.cli.cmd.FoDScanCommands; import com.fortify.cli.fod.session.cli.cmd.FoDSessionCommands; +import com.fortify.cli.fod.user.cli.cmd.FoDUserCommands; +import com.fortify.cli.fod.user_group.cli.cmd.FoDUserGroupCommands; import picocli.CommandLine.Command; @Command( @@ -29,7 +31,9 @@ FoDLookupCommands.class, FoDOssScanCommands.class, FoDSastScanCommands.class, - FoDScanCommands.class + FoDScanCommands.class, + FoDUserCommands.class, + FoDUserGroupCommands.class } ) public class FoDCommands extends AbstractFortifyCLICommand {} diff --git a/fcli-fod/src/main/java/com/fortify/cli/fod/app/cli/cmd/FoDAppCreateCommand.java b/fcli-fod/src/main/java/com/fortify/cli/fod/app/cli/cmd/FoDAppCreateCommand.java index 434c8ed5a4..53a1fc98d9 100644 --- a/fcli-fod/src/main/java/com/fortify/cli/fod/app/cli/cmd/FoDAppCreateCommand.java +++ b/fcli-fod/src/main/java/com/fortify/cli/fod/app/cli/cmd/FoDAppCreateCommand.java @@ -39,6 +39,7 @@ import com.fortify.cli.fod.output.mixin.FoDOutputHelperMixins; import com.fortify.cli.fod.user.helper.FoDUserDescriptor; import com.fortify.cli.fod.user.helper.FoDUserHelper; +import com.fortify.cli.fod.user_group.helper.FoDUserGroupHelper; import io.micronaut.core.annotation.ReflectiveAccess; import kong.unirest.UnirestInstance; import lombok.Getter; @@ -86,7 +87,7 @@ public class FoDAppCreateCommand extends AbstractFoDOutputCommand implements IUn public JsonNode getJsonNode(UnirestInstance unirest) { validate(); - FoDUserDescriptor userDescriptor = FoDUserHelper.getUser(unirest, owner, true); + FoDUserDescriptor userDescriptor = FoDUserHelper.getUserDescriptor(unirest, owner, true); FoDAppTypeOptions.FoDAppType appType = this.appType.getAppType(); FoDAppCreateRequest appCreateRequest = new FoDAppCreateRequest() @@ -103,7 +104,7 @@ public JsonNode getJsonNode(UnirestInstance unirest) { .setMicroservices(FoDAppHelper.getMicroservicesNode(microservices)) .setReleaseMicroserviceName(releaseMicroservice) .setAttributes(FoDAttributeHelper.getAttributesNode(unirest, appAttrs.getAttributes())) - .setUserGroupIds(FoDAppHelper.getUserGroupsNode(unirest, userGroups)); + .setUserGroupIds(FoDUserGroupHelper.getUserGroupsNode(unirest, userGroups)); return FoDAppHelper.createApp(unirest, appCreateRequest).asJsonNode(); } diff --git a/fcli-fod/src/main/java/com/fortify/cli/fod/app/helper/FoDAppHelper.java b/fcli-fod/src/main/java/com/fortify/cli/fod/app/helper/FoDAppHelper.java index f6255a7bd6..10ac2039ca 100644 --- a/fcli-fod/src/main/java/com/fortify/cli/fod/app/helper/FoDAppHelper.java +++ b/fcli-fod/src/main/java/com/fortify/cli/fod/app/helper/FoDAppHelper.java @@ -34,8 +34,6 @@ import com.fortify.cli.fod.microservice.helper.FoDAppMicroserviceHelper; import com.fortify.cli.fod.microservice.helper.FoDAppMicroserviceUpdateRequest; import com.fortify.cli.fod.rest.FoDUrls; -import com.fortify.cli.fod.user_group.helper.FoDUserGroupDescriptor; -import com.fortify.cli.fod.user_group.helper.FoDUserGroupHelper; import io.micronaut.core.util.StringUtils; import kong.unirest.GetRequest; import kong.unirest.UnirestInstance; @@ -133,6 +131,16 @@ public static String getEmailList(ArrayList notifications) { } } + public static JsonNode getApplicationsNode(UnirestInstance unirest, ArrayList applications) { + ArrayNode appArray = getObjectMapper().createArrayNode(); + if (applications == null || applications.isEmpty()) return appArray; + for (String a : applications) { + FoDAppDescriptor appDescriptor = FoDAppHelper.getAppDescriptor(unirest, a, true); + appArray.add(appDescriptor.getApplicationId()); + } + return appArray; + } + public static JsonNode getMicroservicesNode(ArrayList microservices) { ArrayNode microserviceArray = objectMapper.createArrayNode(); if (microservices == null || microservices.isEmpty()) return microserviceArray; @@ -142,25 +150,6 @@ public static JsonNode getMicroservicesNode(ArrayList microservices) { return microserviceArray; } - public static JsonNode getUserGroupsNode(ArrayList userGroups) { - ArrayNode userGroupArray = objectMapper.createArrayNode(); - if (userGroups == null || userGroups.isEmpty()) return userGroupArray; - for (Integer ug : userGroups) { - userGroupArray.add(ug); - } - return userGroupArray; - } - - public static JsonNode getUserGroupsNode(UnirestInstance unirest, ArrayList userGroups) { - ArrayNode userGroupArray = getObjectMapper().createArrayNode(); - if (userGroups == null || userGroups.isEmpty()) return userGroupArray; - for (String ug : userGroups) { - FoDUserGroupDescriptor userGroupDescriptor = FoDUserGroupHelper.getUserGroup(unirest, ug, true); - userGroupArray.add(userGroupDescriptor.getId()); - } - return userGroupArray; - } - public static boolean missing(List list) { return list == null || list.isEmpty(); } diff --git a/fcli-fod/src/main/java/com/fortify/cli/fod/rest/FoDUrls.java b/fcli-fod/src/main/java/com/fortify/cli/fod/rest/FoDUrls.java index 46a0497da4..f44925abc2 100644 --- a/fcli-fod/src/main/java/com/fortify/cli/fod/rest/FoDUrls.java +++ b/fcli-fod/src/main/java/com/fortify/cli/fod/rest/FoDUrls.java @@ -39,8 +39,13 @@ public class FoDUrls { public static final String USERS = ApiBase + "/users"; public static final String USER = ApiBase + "/users/{userId}"; public static final String USER_GROUPS = ApiBase + "/user-management/user-groups"; - public static final String USER_GROUP = ApiBase + "/user-management/user-groups/{userId}"; - public static final String USER_GROUP_MEMBERS = ApiBase + "/user-management/user-groups/{userId}/members"; + public static final String USER_GROUP = ApiBase + "/user-management/user-groups/{groupId}"; + public static final String USER_GROUP_MEMBERS = ApiBase + "/user-management/user-groups/{groupId}/members"; + public static final String USER_APPLICATION_ACCESS = ApiBase + "/user-application-access/{userId}"; + public static final String USER_APPLICATION_ACCESS_DELETE = USER_APPLICATION_ACCESS + "/{applicationId}"; + public static final String USER_GROUP_APPLICATION_ACCESS = ApiBase + "/user-group-application-access/{userGroupId}"; + public static final String USER_GROUP_APPLICATION_ACCESS_DELETE = USER_GROUP_APPLICATION_ACCESS + "/{applicationId}"; + public static final String LOOKUP_ITEMS = ApiBase + "/lookup-items"; public static final String SCANS = ApiBase + "/scans"; public static final String SCAN = ApiBase + "/scans/{scanId}"; diff --git a/fcli-fod/src/main/java/com/fortify/cli/fod/user/cli/cmd/FoDUserCommands.java b/fcli-fod/src/main/java/com/fortify/cli/fod/user/cli/cmd/FoDUserCommands.java new file mode 100644 index 0000000000..4006e95cae --- /dev/null +++ b/fcli-fod/src/main/java/com/fortify/cli/fod/user/cli/cmd/FoDUserCommands.java @@ -0,0 +1,42 @@ +/******************************************************************************* + * (c) Copyright 2020 Micro Focus or one of its affiliates + * + * 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 com.fortify.cli.fod.user.cli.cmd; + +import com.fortify.cli.common.cli.cmd.AbstractFortifyCLICommand; +import com.fortify.cli.common.variable.PredefinedVariable; +import picocli.CommandLine; + +@CommandLine.Command(name = "user", + subcommands = { + FoDUserCreateCommand.class, + FoDUserListCommand.class, + FoDUserGetCommand.class, + FoDUserUpdateCommand.class, + FoDUserDeleteCommand.class + } +) +@PredefinedVariable(name = "_fod_currentUser", field = "userId") +public class FoDUserCommands extends AbstractFortifyCLICommand { +} diff --git a/fcli-fod/src/main/java/com/fortify/cli/fod/user/cli/cmd/FoDUserCreateCommand.java b/fcli-fod/src/main/java/com/fortify/cli/fod/user/cli/cmd/FoDUserCreateCommand.java new file mode 100644 index 0000000000..1d356de692 --- /dev/null +++ b/fcli-fod/src/main/java/com/fortify/cli/fod/user/cli/cmd/FoDUserCreateCommand.java @@ -0,0 +1,110 @@ +/******************************************************************************* + * (c) Copyright 2020 Micro Focus or one of its affiliates + * + * 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 com.fortify.cli.fod.user.cli.cmd; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fortify.cli.common.output.cli.cmd.unirest.IUnirestJsonNodeSupplier; +import com.fortify.cli.common.output.spi.transform.IActionCommandResultSupplier; +import com.fortify.cli.common.output.spi.transform.IRecordTransformer; +import com.fortify.cli.fod.app.helper.FoDAppHelper; +import com.fortify.cli.fod.output.cli.AbstractFoDOutputCommand; +import com.fortify.cli.fod.output.mixin.FoDOutputHelperMixins; +import com.fortify.cli.fod.user.helper.FoDUserCreateRequest; +import com.fortify.cli.fod.user.helper.FoDUserHelper; +import com.fortify.cli.fod.user_group.helper.FoDUserGroupHelper; +import io.micronaut.core.annotation.ReflectiveAccess; +import kong.unirest.UnirestInstance; +import lombok.Getter; +import picocli.CommandLine.Command; +import picocli.CommandLine.Mixin; +import picocli.CommandLine.Option; +import picocli.CommandLine.Parameters; + +import java.util.ArrayList; + +@ReflectiveAccess +@Command(name = FoDOutputHelperMixins.Create.CMD_NAME) +public class FoDUserCreateCommand extends AbstractFoDOutputCommand implements IUnirestJsonNodeSupplier, IRecordTransformer, IActionCommandResultSupplier { + @Getter @Mixin private FoDOutputHelperMixins.Create outputHelper; + + @Parameters(index = "0", arity = "1", descriptionKey = "user-name") + private String userName; + @Option(names = {"--email"}, required = true) + private String email; + @Option(names = {"--firstname"}, required = true) + private String firstName; + @Option(names = {"--lastname"}, required = true) + private String lastName; + @Option(names = {"--phone", "--phone-number"}) + private String phoneNumber; + @Option(names = {"--role"}, required = true) + private String roleNameOrId; + @Option(names = {"--group"}, required = false, arity = "0..*") + private ArrayList userGroups; + @Option(names = {"--application"}, required = false, arity = "0..*") + private ArrayList applications; + + @Override + public JsonNode getJsonNode(UnirestInstance unirest) { + validate(); + + FoDUserCreateRequest userCreateRequest = new FoDUserCreateRequest() + .setUserName(userName) + .setEmail(email) + .setFirstName(firstName) + .setLastName(lastName) + .setPhoneNumber(phoneNumber) + .setRoleId(FoDUserHelper.getRoleId(unirest, roleNameOrId)); + + if (userGroups != null && userGroups.size() > 0) { + userCreateRequest.setUserGroupIds(FoDUserGroupHelper.getUserGroupsNode(unirest, userGroups)); + } + if (applications != null && applications.size() > 0) { + userCreateRequest.setApplicationIds(FoDAppHelper.getApplicationsNode(unirest, applications)); + } + + return FoDUserHelper.createUser(unirest, userCreateRequest).asJsonNode(); + } + + private void validate() { + + } + + @Override + public JsonNode transformRecord(JsonNode record) { + return FoDUserHelper.renameFields(record); + } + + @Override + public String getActionCommandResult() { + return "CREATED"; + } + + @Override + public boolean isSingular() { + return true; + } + +} diff --git a/fcli-fod/src/main/java/com/fortify/cli/fod/user/cli/cmd/FoDUserDeleteCommand.java b/fcli-fod/src/main/java/com/fortify/cli/fod/user/cli/cmd/FoDUserDeleteCommand.java new file mode 100644 index 0000000000..a15b11a5ce --- /dev/null +++ b/fcli-fod/src/main/java/com/fortify/cli/fod/user/cli/cmd/FoDUserDeleteCommand.java @@ -0,0 +1,72 @@ +/******************************************************************************* + * (c) Copyright 2020 Micro Focus or one of its affiliates + * + * 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 com.fortify.cli.fod.user.cli.cmd; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fortify.cli.common.output.cli.cmd.unirest.IUnirestJsonNodeSupplier; +import com.fortify.cli.common.output.spi.transform.IActionCommandResultSupplier; +import com.fortify.cli.common.output.spi.transform.IRecordTransformer; +import com.fortify.cli.fod.output.cli.AbstractFoDOutputCommand; +import com.fortify.cli.fod.output.mixin.FoDOutputHelperMixins; +import com.fortify.cli.fod.rest.FoDUrls; +import com.fortify.cli.fod.user.cli.mixin.FoDUserResolverMixin; +import com.fortify.cli.fod.user.helper.FoDUserDescriptor; +import com.fortify.cli.fod.user.helper.FoDUserHelper; +import io.micronaut.core.annotation.ReflectiveAccess; +import kong.unirest.UnirestInstance; +import lombok.Getter; +import picocli.CommandLine.Command; +import picocli.CommandLine.Mixin; + +@ReflectiveAccess +@Command(name = FoDOutputHelperMixins.Delete.CMD_NAME) +public class FoDUserDeleteCommand extends AbstractFoDOutputCommand implements IUnirestJsonNodeSupplier, IRecordTransformer, IActionCommandResultSupplier { + @Getter @Mixin private FoDOutputHelperMixins.Delete outputHelper; + @Mixin private FoDUserResolverMixin.PositionalParameter userResolver; + + @Override + public JsonNode getJsonNode(UnirestInstance unirest) { + FoDUserDescriptor userDescriptor = FoDUserHelper.getUserDescriptor(unirest, userResolver.getUserNameOrId(), true); + unirest.delete(FoDUrls.USER) + .routeParam("userId", String.valueOf(userDescriptor.getUserId())) + .asObject(JsonNode.class).getBody(); + return userDescriptor.asObjectNode(); + } + + @Override + public JsonNode transformRecord(JsonNode record) { + return FoDUserHelper.renameFields(record); + } + + @Override + public String getActionCommandResult() { + return "DELETED"; + } + + @Override + public boolean isSingular() { + return true; + } +} diff --git a/fcli-fod/src/main/java/com/fortify/cli/fod/user/cli/cmd/FoDUserGetCommand.java b/fcli-fod/src/main/java/com/fortify/cli/fod/user/cli/cmd/FoDUserGetCommand.java new file mode 100644 index 0000000000..418169568c --- /dev/null +++ b/fcli-fod/src/main/java/com/fortify/cli/fod/user/cli/cmd/FoDUserGetCommand.java @@ -0,0 +1,61 @@ +/******************************************************************************* + * (c) Copyright 2020 Micro Focus or one of its affiliates + * + * 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 com.fortify.cli.fod.user.cli.cmd; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fortify.cli.common.output.cli.cmd.unirest.IUnirestJsonNodeSupplier; +import com.fortify.cli.common.output.spi.transform.IRecordTransformer; +import com.fortify.cli.fod.output.cli.AbstractFoDOutputCommand; +import com.fortify.cli.fod.output.mixin.FoDOutputHelperMixins; +import com.fortify.cli.fod.user.cli.mixin.FoDUserResolverMixin; +import com.fortify.cli.fod.user.helper.FoDUserHelper; +import io.micronaut.core.annotation.ReflectiveAccess; +import kong.unirest.UnirestInstance; +import lombok.Getter; +import picocli.CommandLine.Command; +import picocli.CommandLine.Mixin; + +@ReflectiveAccess +@Command(name = FoDOutputHelperMixins.Get.CMD_NAME) +public class FoDUserGetCommand extends AbstractFoDOutputCommand implements IUnirestJsonNodeSupplier, IRecordTransformer { + @Getter @Mixin private FoDOutputHelperMixins.Get outputHelper; + @Mixin private FoDUserResolverMixin.PositionalParameter userResolver; + + @Override + public JsonNode getJsonNode(UnirestInstance unirest) { + return userResolver.getUserDescriptor(unirest).asJsonNode(); + } + + @Override + public JsonNode transformRecord(JsonNode record) { + return FoDUserHelper.renameFields(record); + } + + @Override + public boolean isSingular() { + return true; + } + +} diff --git a/fcli-fod/src/main/java/com/fortify/cli/fod/user/cli/cmd/FoDUserListCommand.java b/fcli-fod/src/main/java/com/fortify/cli/fod/user/cli/cmd/FoDUserListCommand.java new file mode 100644 index 0000000000..ca4a1b7c69 --- /dev/null +++ b/fcli-fod/src/main/java/com/fortify/cli/fod/user/cli/cmd/FoDUserListCommand.java @@ -0,0 +1,69 @@ +/******************************************************************************* + * (c) Copyright 2020 Micro Focus or one of its affiliates + * + * 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 com.fortify.cli.fod.user.cli.cmd; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fortify.cli.common.output.cli.cmd.unirest.IUnirestBaseRequestSupplier; +import com.fortify.cli.common.output.spi.transform.IRecordTransformer; +import com.fortify.cli.fod.output.cli.AbstractFoDOutputCommand; +import com.fortify.cli.fod.output.mixin.FoDOutputHelperMixins; +import com.fortify.cli.fod.rest.FoDUrls; +import com.fortify.cli.fod.rest.query.FoDFilterParamGenerator; +import com.fortify.cli.fod.rest.query.FoDFiltersParamValueGenerators; +import com.fortify.cli.fod.rest.query.IFoDFilterParamGeneratorSupplier; +import com.fortify.cli.fod.user.helper.FoDUserHelper; +import io.micronaut.core.annotation.ReflectiveAccess; +import kong.unirest.HttpRequest; +import kong.unirest.UnirestInstance; +import lombok.Getter; +import picocli.CommandLine.Command; +import picocli.CommandLine.Mixin; + +@ReflectiveAccess +@Command(name = FoDOutputHelperMixins.List.CMD_NAME) +public class FoDUserListCommand extends AbstractFoDOutputCommand implements IUnirestBaseRequestSupplier, IRecordTransformer, IFoDFilterParamGeneratorSupplier { + @Getter @Mixin private FoDOutputHelperMixins.List outputHelper; + + @Getter private FoDFilterParamGenerator filterParamGenerator = new FoDFilterParamGenerator() + .add("userId","userId", FoDFiltersParamValueGenerators::plain) + .add("userName","userName", FoDFiltersParamValueGenerators::plain) + .add("email", "email", FoDFiltersParamValueGenerators::plain) + .add("roleName", "roleName", FoDFiltersParamValueGenerators::plain); + + @Override + public HttpRequest getBaseRequest(UnirestInstance unirest) { + return unirest.get(FoDUrls.USERS); + } + + @Override + public JsonNode transformRecord(JsonNode record) { + return FoDUserHelper.renameFields(record); + } + + @Override + public boolean isSingular() { + return false; + } +} diff --git a/fcli-fod/src/main/java/com/fortify/cli/fod/user/cli/cmd/FoDUserUpdateCommand.java b/fcli-fod/src/main/java/com/fortify/cli/fod/user/cli/cmd/FoDUserUpdateCommand.java new file mode 100644 index 0000000000..f57f43b89a --- /dev/null +++ b/fcli-fod/src/main/java/com/fortify/cli/fod/user/cli/cmd/FoDUserUpdateCommand.java @@ -0,0 +1,140 @@ +/******************************************************************************* + * (c) Copyright 2020 Micro Focus or one of its affiliates + * + * 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 com.fortify.cli.fod.user.cli.cmd; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fortify.cli.common.output.cli.cmd.unirest.IUnirestJsonNodeSupplier; +import com.fortify.cli.common.output.spi.transform.IActionCommandResultSupplier; +import com.fortify.cli.common.output.spi.transform.IRecordTransformer; +import com.fortify.cli.fod.app.helper.FoDAppHelper; +import com.fortify.cli.fod.output.cli.AbstractFoDOutputCommand; +import com.fortify.cli.fod.output.mixin.FoDOutputHelperMixins; +import com.fortify.cli.fod.user.cli.mixin.FoDUserResolverMixin; +import com.fortify.cli.fod.user.helper.FoDUserDescriptor; +import com.fortify.cli.fod.user.helper.FoDUserHelper; +import com.fortify.cli.fod.user.helper.FoDUserUpdateRequest; +import com.fortify.cli.fod.user_group.helper.FoDUserGroupHelper; +import io.micronaut.core.annotation.ReflectiveAccess; +import io.micronaut.core.util.StringUtils; +import kong.unirest.UnirestInstance; +import lombok.Getter; +import picocli.CommandLine.Command; +import picocli.CommandLine.Mixin; +import picocli.CommandLine.Option; + +import java.util.ArrayList; + +@ReflectiveAccess +@Command(name = FoDOutputHelperMixins.Update.CMD_NAME) +public class FoDUserUpdateCommand extends AbstractFoDOutputCommand implements IUnirestJsonNodeSupplier, IRecordTransformer, IActionCommandResultSupplier { + @Getter @Mixin private FoDOutputHelperMixins.Update outputHelper; + @Mixin private FoDUserResolverMixin.PositionalParameter userResolver; + + @Option(names = {"--email"}) + private String email; + @Option(names = {"--firstname"}) + private String firstName; + @Option(names = {"--lastname"}) + private String lastName; + @Option(names = {"--phone", "--phone-number"}) + private String phoneNumber; + @Option(names = {"--password"}) + private String password; + @Option(names = {"--role"}) + private String roleNameOrId; + @Option(names = {"--password-never-expires"}) + private Boolean passwordNeverExpires = false; + @Option(names = {"--suspended"}) + private Boolean isSuspended = false; + @Option(names = {"--must-change"}) + private Boolean mustChange = false; + @Option(names = {"--add-group"}, required = false, arity = "0..*") + private ArrayList addUserGroups; + @Option(names = {"--remove-group"}, required = false, arity = "0..*") + private ArrayList removeUserGroups; + @Option(names = {"--add-app", "--add-application"}, required = false, arity = "0..*") + private ArrayList addApplications; + @Option(names = {"--remove-app", "--remove-application"}, required = false, arity = "0..*") + private ArrayList removeApplications; + + @Override + public JsonNode getJsonNode(UnirestInstance unirest) { + validate(); + + int roleId = 0; + FoDUserDescriptor userDescriptor = userResolver.getUserDescriptor(unirest); + if (roleNameOrId != null && !roleNameOrId.isEmpty()) { + roleId = FoDUserHelper.getRoleId(unirest, roleNameOrId); + } + + FoDUserUpdateRequest userUpdateRequest = new FoDUserUpdateRequest() + .setEmail(email != null && StringUtils.isNotEmpty(email) ? email : userDescriptor.getUserName()) + .setFirstName(firstName != null && StringUtils.isNotEmpty(firstName) ? firstName : userDescriptor.getFirstName()) + .setLastName(lastName != null && StringUtils.isNotEmpty(lastName) ? lastName : userDescriptor.getLastName()) + .setPhoneNumber(phoneNumber != null && StringUtils.isNotEmpty(phoneNumber) ? phoneNumber : userDescriptor.getPhoneNumber()) + .setRoleId(roleId > 0 ? roleId : userDescriptor.getRoleId()) + .setPasswordNeverExpires(passwordNeverExpires) + .setIsSuspended(isSuspended) + .setMustChange(mustChange); + + if (password != null && StringUtils.isNotEmpty(password)) { + userUpdateRequest.setPassword(password); + } + if (addUserGroups != null && addUserGroups.size() > 0) { + userUpdateRequest.setAddUserGroups(FoDUserGroupHelper.getUserGroupsNode(unirest, addUserGroups)); + } + if (removeUserGroups != null && removeUserGroups.size() > 0) { + userUpdateRequest.setRemoveUserGroups(FoDUserGroupHelper.getUserGroupsNode(unirest, removeUserGroups)); + } + if (addApplications != null && addApplications.size() > 0) { + userUpdateRequest.setAddApplications(FoDAppHelper.getApplicationsNode(unirest, addApplications)); + } + if (removeApplications != null && removeApplications.size() > 0) { + userUpdateRequest.setRemoveApplications(FoDAppHelper.getApplicationsNode(unirest, removeApplications)); + } + + return FoDUserHelper.updateUser(unirest, userDescriptor.getUserId(), userUpdateRequest).asJsonNode(); + } + + private void validate() { + + } + + @Override + public JsonNode transformRecord(JsonNode record) { + return FoDUserHelper.renameFields(record); + } + + @Override + public String getActionCommandResult() { + return "UPDATED"; + } + + @Override + public boolean isSingular() { + return true; + } + +} diff --git a/fcli-fod/src/main/java/com/fortify/cli/fod/user/cli/mixin/FoDUserResolverMixin.java b/fcli-fod/src/main/java/com/fortify/cli/fod/user/cli/mixin/FoDUserResolverMixin.java new file mode 100644 index 0000000000..4bcd8273f6 --- /dev/null +++ b/fcli-fod/src/main/java/com/fortify/cli/fod/user/cli/mixin/FoDUserResolverMixin.java @@ -0,0 +1,74 @@ +/******************************************************************************* + * (c) Copyright 2020 Micro Focus or one of its affiliates + * + * 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 com.fortify.cli.fod.user.cli.mixin; + +import com.fortify.cli.common.variable.AbstractPredefinedVariableResolverMixin; +import com.fortify.cli.fod.user.cli.cmd.FoDUserCommands; +import com.fortify.cli.fod.user.helper.FoDUserDescriptor; +import com.fortify.cli.fod.user.helper.FoDUserHelper; +import io.micronaut.core.annotation.ReflectiveAccess; +import kong.unirest.UnirestInstance; +import lombok.Getter; +import picocli.CommandLine.Option; +import picocli.CommandLine.Parameters; + +public class FoDUserResolverMixin { + @ReflectiveAccess + public static abstract class AbstractFoDUserResolverMixin extends AbstractPredefinedVariableResolverMixin { + public abstract String getUserNameOrId(); + + public FoDUserDescriptor getUserDescriptor(UnirestInstance unirest, String... fields){ + return FoDUserHelper.getUserDescriptor(unirest, resolvePredefinedVariable(getUserNameOrId()), true); + } + + public String getUserId(UnirestInstance unirest) { + return getUserDescriptor(unirest, "userId").getUserId().toString(); + } + + @Override + protected Class getPredefinedVariableClass() { + return FoDUserCommands.class; + } + } + + @ReflectiveAccess + public static class RequiredOption extends AbstractFoDUserResolverMixin { + @Option(names = {"--user"}, required = true, descriptionKey = "UserMixin") + @Getter private String userNameOrId; + } + + @ReflectiveAccess + public static class OptionalOption extends AbstractFoDUserResolverMixin { + @Option(names = {"--user"}, required = false, descriptionKey = "UserMixin") + @Getter private String userNameOrId; + } + + @ReflectiveAccess + public static class PositionalParameter extends AbstractFoDUserResolverMixin { + @Parameters(index = "0", arity = "1", descriptionKey = "UserMixin") + @Getter private String userNameOrId; + } +} \ No newline at end of file diff --git a/fcli-fod/src/main/java/com/fortify/cli/fod/user/helper/FoDUserAppAccessRequest.java b/fcli-fod/src/main/java/com/fortify/cli/fod/user/helper/FoDUserAppAccessRequest.java new file mode 100644 index 0000000000..75d5418d18 --- /dev/null +++ b/fcli-fod/src/main/java/com/fortify/cli/fod/user/helper/FoDUserAppAccessRequest.java @@ -0,0 +1,42 @@ +/******************************************************************************* + * (c) Copyright 2020 Micro Focus or one of its affiliates + * + * 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 com.fortify.cli.fod.user.helper; + +import io.micronaut.core.annotation.ReflectiveAccess; +import lombok.Getter; +import lombok.ToString; + +@ReflectiveAccess +@Getter +@ToString +public class FoDUserAppAccessRequest { + private Integer applicationId; + + public FoDUserAppAccessRequest setApplicationId(Integer id) { + this.applicationId = id; + return this; + } + +} diff --git a/fcli-fod/src/main/java/com/fortify/cli/fod/user/helper/FoDUserCreateRequest.java b/fcli-fod/src/main/java/com/fortify/cli/fod/user/helper/FoDUserCreateRequest.java new file mode 100644 index 0000000000..f9f3a8ca13 --- /dev/null +++ b/fcli-fod/src/main/java/com/fortify/cli/fod/user/helper/FoDUserCreateRequest.java @@ -0,0 +1,97 @@ +/******************************************************************************* + * (c) Copyright 2020 Micro Focus or one of its affiliates + * + * 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 com.fortify.cli.fod.user.helper; + +import com.fasterxml.jackson.databind.JsonNode; +import io.micronaut.core.annotation.ReflectiveAccess; +import lombok.Getter; +import lombok.ToString; + +@ReflectiveAccess +@Getter +@ToString +public class FoDUserCreateRequest { + private String userName; + private String email; + private String firstName; + private String lastName; + private String phoneNumber; + private Integer roleId; + private Boolean passwordNeverExpires = false; + private Boolean isSuspended = false; + private JsonNode userGroupIds; + private JsonNode applicationIds; + + public FoDUserCreateRequest setUserName(String userName) { + this.userName = userName; + return this; + } + + public FoDUserCreateRequest setEmail(String email) { + this.email = email; + return this; + } + + public FoDUserCreateRequest setFirstName(String firstName) { + this.firstName = firstName; + return this; + } + + public FoDUserCreateRequest setLastName(String lastName) { + this.lastName = lastName; + return this; + } + + public FoDUserCreateRequest setPhoneNumber(String phoneNumber) { + this.phoneNumber = (phoneNumber == null ? "" : phoneNumber); + return this; + } + + public FoDUserCreateRequest setRoleId(Integer roleId) { + this.roleId = roleId; + return this; + } + + public FoDUserCreateRequest setPasswordNeverExpires(Boolean passwordNeverExpires) { + this.passwordNeverExpires = passwordNeverExpires; + return this; + } + + public FoDUserCreateRequest setIsSuspended(Boolean isSuspended) { + this.isSuspended = isSuspended; + return this; + } + + public FoDUserCreateRequest setUserGroupIds(JsonNode ids) { + this.userGroupIds = ids; + return this; + } + + public FoDUserCreateRequest setApplicationIds(JsonNode ids) { + this.applicationIds = ids; + return this; + } + +} diff --git a/fcli-fod/src/main/java/com/fortify/cli/fod/user/helper/FoDUserDescriptor.java b/fcli-fod/src/main/java/com/fortify/cli/fod/user/helper/FoDUserDescriptor.java index 6c2510e0db..5092e2d42c 100644 --- a/fcli-fod/src/main/java/com/fortify/cli/fod/user/helper/FoDUserDescriptor.java +++ b/fcli-fod/src/main/java/com/fortify/cli/fod/user/helper/FoDUserDescriptor.java @@ -24,7 +24,6 @@ ******************************************************************************/ package com.fortify.cli.fod.user.helper; -import com.fasterxml.jackson.annotation.JsonProperty; import com.fortify.cli.common.json.JsonNodeHolder; import io.micronaut.core.annotation.ReflectiveAccess; import lombok.Data; diff --git a/fcli-fod/src/main/java/com/fortify/cli/fod/user/helper/FoDUserHelper.java b/fcli-fod/src/main/java/com/fortify/cli/fod/user/helper/FoDUserHelper.java index a33bff16ed..061f3f34b7 100644 --- a/fcli-fod/src/main/java/com/fortify/cli/fod/user/helper/FoDUserHelper.java +++ b/fcli-fod/src/main/java/com/fortify/cli/fod/user/helper/FoDUserHelper.java @@ -24,18 +24,37 @@ ******************************************************************************/ package com.fortify.cli.fod.user.helper; +import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ArrayNode; import com.fasterxml.jackson.databind.node.ObjectNode; import com.fortify.cli.common.json.JsonHelper; -import com.fortify.cli.fod.attribute.helper.FoDAttributeDescriptor; +import com.fortify.cli.common.output.transform.fields.RenameFieldsTransformer; +import com.fortify.cli.fod.app.helper.FoDAppDescriptor; +import com.fortify.cli.fod.app.helper.FoDAppHelper; +import com.fortify.cli.fod.lookup.cli.mixin.FoDLookupTypeOptions; +import com.fortify.cli.fod.lookup.helper.FoDLookupDescriptor; +import com.fortify.cli.fod.lookup.helper.FoDLookupHelper; import com.fortify.cli.fod.rest.FoDUrls; +import com.fortify.cli.fod.user_group.helper.FoDUserGroupHelper; +import com.fortify.cli.fod.util.FoDEnums; import kong.unirest.GetRequest; import kong.unirest.UnirestInstance; +import lombok.Getter; import javax.validation.ValidationException; +import java.util.ArrayList; public class FoDUserHelper { - public static final FoDUserDescriptor getUser(UnirestInstance unirestInstance, String userNameOrId, boolean failIfNotFound) { + @Getter + private static ObjectMapper objectMapper = new ObjectMapper(); + + public static final JsonNode renameFields(JsonNode record) { + return new RenameFieldsTransformer(new String[]{}).transform(record); + } + + public static final FoDUserDescriptor getUserDescriptor(UnirestInstance unirestInstance, String userNameOrId, boolean failIfNotFound) { GetRequest request = unirestInstance.get(FoDUrls.USERS); try { int attrId = Integer.parseInt(userNameOrId); @@ -51,4 +70,128 @@ public static final FoDUserDescriptor getUser(UnirestInstance unirestInstance, S } return attr.size() == 0 ? null : JsonHelper.treeToValue(attr.get(0), FoDUserDescriptor.class); } + + public static final FoDUserDescriptor getUserDescriptorById(UnirestInstance unirest, String userId, boolean failIfNotFound) { + GetRequest request = unirest.get(FoDUrls.USER).routeParam("userId", userId); + JsonNode user = request.asObject(ObjectNode.class).getBody(); + if (failIfNotFound && user.get("userName").asText().isEmpty()) { + throw new ValidationException("No user found for id: " + userId); + } + return getDescriptor(user); + } + + public static final FoDUserDescriptor createUser(UnirestInstance unirest, FoDUserCreateRequest userCreateRequest) { + ObjectNode body = objectMapper.valueToTree(userCreateRequest); + JsonNode response = unirest.post(FoDUrls.USERS) + .body(body).asObject(JsonNode.class).getBody(); + FoDUserDescriptor descriptor = JsonHelper.treeToValue(response, FoDUserDescriptor.class); + descriptor.asObjectNode() + .put("userName", userCreateRequest.getUserName()) + .put("firstName", userCreateRequest.getFirstName()) + .put("lastName", userCreateRequest.getLastName()) + .put("email", userCreateRequest.getEmail()); + // add user to any groups specified + ArrayList groupsToUpdate = objectMapper.convertValue(userCreateRequest.getUserGroupIds(), ArrayList.class); + if (userCreateRequest.getUserGroupIds() != null && userCreateRequest.getUserGroupIds().size() > 0) { + for (Integer groupId: groupsToUpdate) { + FoDUserGroupHelper.updateUserGroupMembership(unirest, userCreateRequest.getUserName(), String.valueOf(groupId), FoDEnums.UserGroupMembershipAction.Add); + } + } + // add user to any applications specified + ArrayList appsToUpdate = objectMapper.convertValue(userCreateRequest.getApplicationIds(), ArrayList.class); + if (userCreateRequest.getApplicationIds() != null && userCreateRequest.getApplicationIds().size() > 0) { + for (Integer appId: appsToUpdate) { + FoDUserHelper.updateUserApplicationAccess(unirest, userCreateRequest.getUserName(), String.valueOf(appId), FoDEnums.UserApplicationAccessAction.Add); + } + } + return descriptor; + } + + public static final FoDUserDescriptor updateUser(UnirestInstance unirest, Integer userId, + FoDUserUpdateRequest userUpdateRequest) { + ObjectNode body = objectMapper.valueToTree(userUpdateRequest); + FoDUserDescriptor userDescriptor = getUserDescriptor(unirest, String.valueOf(userId), true); + unirest.put(FoDUrls.USER) + .routeParam("userId", String.valueOf(userId)) + .body(body).asObject(JsonNode.class).getBody(); + // add user to any groups specified + ArrayList groupsToUpdate = objectMapper.convertValue(userUpdateRequest.getAddUserGroups(), ArrayList.class); + if (userUpdateRequest.getAddUserGroups() != null && userUpdateRequest.getAddUserGroups().size() > 0) { + for (Integer groupId: groupsToUpdate) { + FoDUserGroupHelper.updateUserGroupMembership(unirest, userDescriptor.getUserName(), String.valueOf(groupId), FoDEnums.UserGroupMembershipAction.Add); + } + } + // remove user from any groups specified + groupsToUpdate = objectMapper.convertValue(userUpdateRequest.getRemoveUserGroups(), ArrayList.class); + if (userUpdateRequest.getRemoveUserGroups() != null && userUpdateRequest.getRemoveUserGroups().size() > 0) { + for (Integer groupId: groupsToUpdate) { + FoDUserGroupHelper.updateUserGroupMembership(unirest, userDescriptor.getUserName(), String.valueOf(groupId), FoDEnums.UserGroupMembershipAction.Remove); + } + } + // add user to any applications specified + ArrayList appsToUpdate = objectMapper.convertValue(userUpdateRequest.getAddApplications(), ArrayList.class); + if (userUpdateRequest.getAddApplications() != null && userUpdateRequest.getAddApplications().size() > 0) { + for (Integer appId: appsToUpdate) { + FoDUserHelper.updateUserApplicationAccess(unirest, String.valueOf(userId), String.valueOf(appId), FoDEnums.UserApplicationAccessAction.Add); + } + } + // remove user from any applications specified + appsToUpdate = objectMapper.convertValue(userUpdateRequest.getRemoveApplications(), ArrayList.class); + if (userUpdateRequest.getRemoveApplications() != null && userUpdateRequest.getRemoveApplications().size() > 0) { + for (Integer appId: appsToUpdate) { + FoDUserHelper.updateUserApplicationAccess(unirest, String.valueOf(userId), String.valueOf(appId), FoDEnums.UserApplicationAccessAction.Remove); + } + } + return getUserDescriptorById(unirest, String.valueOf(userId), true); + } + + public static final FoDUserDescriptor updateUserApplicationAccess(UnirestInstance unirest, String userNameOrId, String appNameOrId, + FoDEnums.UserApplicationAccessAction action) { + FoDUserDescriptor userDescriptor = FoDUserHelper.getUserDescriptor(unirest, userNameOrId, true); + FoDAppDescriptor appDescriptor = FoDAppHelper.getAppDescriptor(unirest, appNameOrId, true); + if (action.equals(FoDEnums.UserApplicationAccessAction.Add)) { + FoDUserAppAccessRequest appAccessRequest = new FoDUserAppAccessRequest() + .setApplicationId(appDescriptor.getApplicationId()); + ObjectNode body = objectMapper.valueToTree(appAccessRequest); + unirest.post(FoDUrls.USER_APPLICATION_ACCESS).routeParam("userId", String.valueOf(userDescriptor.getUserId())) + .body(body).asEmpty(); + } else if (action.equals(FoDEnums.UserApplicationAccessAction.Remove)) { + unirest.delete(FoDUrls.USER_APPLICATION_ACCESS_DELETE) + .routeParam("userId", String.valueOf(userDescriptor.getUserId())) + .routeParam("applicationId", String.valueOf(appDescriptor.getApplicationId())) + .asEmpty(); + } else { + throw new ValidationException("Invalid action specified when updating users application access"); + } + return userDescriptor; + } + + public static Integer getRoleId(UnirestInstance unirest, String roleNameOrId) { + int roleId = 0; + try { + roleId = Integer.parseInt(roleNameOrId); + } catch (NumberFormatException nfe) { + try { + FoDLookupDescriptor lookupDescriptor = FoDLookupHelper.getTextValue(unirest, FoDLookupTypeOptions.FoDLookupType.Roles, roleNameOrId, true); + roleId = Integer.valueOf(lookupDescriptor.getValue()); + } catch (JsonProcessingException e) { + throw new ValidationException("Unable to find role with name: " + roleNameOrId); + } + } + return roleId; + } + + public static JsonNode getUsersNode(UnirestInstance unirest, ArrayList users) { + ArrayNode userArray = getObjectMapper().createArrayNode(); + if (users == null || users.isEmpty()) return userArray; + for (String u : users) { + FoDUserDescriptor userDescriptor = FoDUserHelper.getUserDescriptor(unirest, u, true); + userArray.add(userDescriptor.getUserId()); + } + return userArray; + } + + private static final FoDUserDescriptor getDescriptor(JsonNode node) { + return JsonHelper.treeToValue(node, FoDUserDescriptor.class); + } } diff --git a/fcli-fod/src/main/java/com/fortify/cli/fod/user/helper/FoDUserUpdateRequest.java b/fcli-fod/src/main/java/com/fortify/cli/fod/user/helper/FoDUserUpdateRequest.java new file mode 100644 index 0000000000..cd56fb02da --- /dev/null +++ b/fcli-fod/src/main/java/com/fortify/cli/fod/user/helper/FoDUserUpdateRequest.java @@ -0,0 +1,115 @@ +/******************************************************************************* + * (c) Copyright 2020 Micro Focus or one of its affiliates + * + * 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 com.fortify.cli.fod.user.helper; + +import com.fasterxml.jackson.databind.JsonNode; +import io.micronaut.core.annotation.ReflectiveAccess; +import lombok.Getter; +import lombok.ToString; + +@ReflectiveAccess +@Getter +@ToString +public class FoDUserUpdateRequest { + private String email; + private String firstName; + private String lastName; + private String phoneNumber; + private String password; + private Integer roleId; + private Boolean passwordNeverExpires = false; + private Boolean isSuspended = false; + private Boolean mustChange = false; + private JsonNode addUserGroups; + private JsonNode removeUserGroups; + private JsonNode addApplications; + private JsonNode removeApplications; + + public FoDUserUpdateRequest setEmail(String email) { + this.email = email; + return this; + } + + public FoDUserUpdateRequest setFirstName(String firstName) { + this.firstName = firstName; + return this; + } + + public FoDUserUpdateRequest setLastName(String lastName) { + this.lastName = lastName; + return this; + } + + public FoDUserUpdateRequest setPhoneNumber(String phoneNumber) { + this.phoneNumber = (phoneNumber == null ? "" : phoneNumber); + return this; + } + + public FoDUserUpdateRequest setPassword(String password) { + this.password = (password == null ? "" : password); + return this; + } + + public FoDUserUpdateRequest setRoleId(Integer roleId) { + this.roleId = roleId; + return this; + } + + public FoDUserUpdateRequest setPasswordNeverExpires(Boolean passwordNeverExpires) { + this.passwordNeverExpires = passwordNeverExpires; + return this; + } + + public FoDUserUpdateRequest setIsSuspended(Boolean isSuspended) { + this.isSuspended = isSuspended; + return this; + } + + public FoDUserUpdateRequest setMustChange(Boolean mustChange) { + this.mustChange = mustChange; + return this; + } + + public FoDUserUpdateRequest setAddUserGroups(JsonNode ids) { + this.addUserGroups = ids; + return this; + } + + public FoDUserUpdateRequest setRemoveUserGroups(JsonNode ids) { + this.removeUserGroups = ids; + return this; + } + + public FoDUserUpdateRequest setAddApplications(JsonNode ids) { + this.addApplications = ids; + return this; + } + + public FoDUserUpdateRequest setRemoveApplications(JsonNode ids) { + this.removeApplications = ids; + return this; + } + +} diff --git a/fcli-fod/src/main/java/com/fortify/cli/fod/user_group/cli/cmd/FoDUserGroupCommands.java b/fcli-fod/src/main/java/com/fortify/cli/fod/user_group/cli/cmd/FoDUserGroupCommands.java new file mode 100644 index 0000000000..489e1c389d --- /dev/null +++ b/fcli-fod/src/main/java/com/fortify/cli/fod/user_group/cli/cmd/FoDUserGroupCommands.java @@ -0,0 +1,42 @@ +/******************************************************************************* + * (c) Copyright 2020 Micro Focus or one of its affiliates + * + * 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 com.fortify.cli.fod.user_group.cli.cmd; + +import com.fortify.cli.common.cli.cmd.AbstractFortifyCLICommand; +import com.fortify.cli.common.variable.PredefinedVariable; +import picocli.CommandLine; + +@CommandLine.Command(name = "user-group", + subcommands = { + FoDUserGroupCreateCommand.class, + FoDUserGroupListCommand.class, + FoDUserGroupGetCommand.class, + FoDUserGroupUpdateCommand.class, + FoDUserGroupDeleteCommand.class + } +) +@PredefinedVariable(name = "_fod_currentUserGroup", field = "id") +public class FoDUserGroupCommands extends AbstractFortifyCLICommand { +} diff --git a/fcli-fod/src/main/java/com/fortify/cli/fod/user_group/cli/cmd/FoDUserGroupCreateCommand.java b/fcli-fod/src/main/java/com/fortify/cli/fod/user_group/cli/cmd/FoDUserGroupCreateCommand.java new file mode 100644 index 0000000000..1117e79e9a --- /dev/null +++ b/fcli-fod/src/main/java/com/fortify/cli/fod/user_group/cli/cmd/FoDUserGroupCreateCommand.java @@ -0,0 +1,93 @@ +/******************************************************************************* + * (c) Copyright 2020 Micro Focus or one of its affiliates + * + * 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 com.fortify.cli.fod.user_group.cli.cmd; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fortify.cli.common.output.cli.cmd.unirest.IUnirestJsonNodeSupplier; +import com.fortify.cli.common.output.spi.transform.IActionCommandResultSupplier; +import com.fortify.cli.common.output.spi.transform.IRecordTransformer; +import com.fortify.cli.fod.app.helper.FoDAppHelper; +import com.fortify.cli.fod.output.cli.AbstractFoDOutputCommand; +import com.fortify.cli.fod.output.mixin.FoDOutputHelperMixins; +import com.fortify.cli.fod.user.helper.FoDUserHelper; +import com.fortify.cli.fod.user_group.helper.FoDUserGroupCreateRequest; +import com.fortify.cli.fod.user_group.helper.FoDUserGroupHelper; +import io.micronaut.core.annotation.ReflectiveAccess; +import kong.unirest.UnirestInstance; +import lombok.Getter; +import picocli.CommandLine.Command; +import picocli.CommandLine.Mixin; +import picocli.CommandLine.Option; +import picocli.CommandLine.Parameters; + +import java.util.ArrayList; + +@ReflectiveAccess +@Command(name = FoDOutputHelperMixins.Create.CMD_NAME) +public class FoDUserGroupCreateCommand extends AbstractFoDOutputCommand implements IUnirestJsonNodeSupplier, IRecordTransformer, IActionCommandResultSupplier { + @Getter @Mixin private FoDOutputHelperMixins.Create outputHelper; + + @Parameters(index = "0", arity = "1", descriptionKey = "group-name") + private String groupName; + @Option(names = {"--add-all-users"}) + private Boolean addAllUsers = false; + @Option(names = {"--user"}, required = false, arity = "0..*") + private ArrayList users; + @Option(names = {"--application"}, required = false, arity = "0..*") + private ArrayList applications; + + @Override + public JsonNode getJsonNode(UnirestInstance unirest) { + validate(); + + FoDUserGroupCreateRequest userGroupCreateRequest = new FoDUserGroupCreateRequest() + .setName(groupName) + .setAddAllUsers(addAllUsers) + .setApplications(FoDAppHelper.getApplicationsNode(unirest, applications)) + .setUsers(FoDUserHelper.getUsersNode(unirest, users)); + + return FoDUserGroupHelper.createUserGroup(unirest, userGroupCreateRequest).asJsonNode(); + } + + private void validate() { + + } + + @Override + public JsonNode transformRecord(JsonNode record) { + return FoDUserGroupHelper.renameFields(record); + } + + @Override + public String getActionCommandResult() { + return "CREATED"; + } + + @Override + public boolean isSingular() { + return true; + } + +} diff --git a/fcli-fod/src/main/java/com/fortify/cli/fod/user_group/cli/cmd/FoDUserGroupDeleteCommand.java b/fcli-fod/src/main/java/com/fortify/cli/fod/user_group/cli/cmd/FoDUserGroupDeleteCommand.java new file mode 100644 index 0000000000..cb9ba2e92c --- /dev/null +++ b/fcli-fod/src/main/java/com/fortify/cli/fod/user_group/cli/cmd/FoDUserGroupDeleteCommand.java @@ -0,0 +1,72 @@ +/******************************************************************************* + * (c) Copyright 2020 Micro Focus or one of its affiliates + * + * 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 com.fortify.cli.fod.user_group.cli.cmd; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fortify.cli.common.output.cli.cmd.unirest.IUnirestJsonNodeSupplier; +import com.fortify.cli.common.output.spi.transform.IActionCommandResultSupplier; +import com.fortify.cli.common.output.spi.transform.IRecordTransformer; +import com.fortify.cli.fod.output.cli.AbstractFoDOutputCommand; +import com.fortify.cli.fod.output.mixin.FoDOutputHelperMixins; +import com.fortify.cli.fod.rest.FoDUrls; +import com.fortify.cli.fod.user_group.cli.mixin.FoDUserGroupResolverMixin; +import com.fortify.cli.fod.user_group.helper.FoDUserGroupDescriptor; +import com.fortify.cli.fod.user_group.helper.FoDUserGroupHelper; +import io.micronaut.core.annotation.ReflectiveAccess; +import kong.unirest.UnirestInstance; +import lombok.Getter; +import picocli.CommandLine.Command; +import picocli.CommandLine.Mixin; + +@ReflectiveAccess +@Command(name = FoDOutputHelperMixins.Delete.CMD_NAME) +public class FoDUserGroupDeleteCommand extends AbstractFoDOutputCommand implements IUnirestJsonNodeSupplier, IRecordTransformer, IActionCommandResultSupplier { + @Getter @Mixin private FoDOutputHelperMixins.Delete outputHelper; + @Mixin private FoDUserGroupResolverMixin.PositionalParameter userGroupResolver; + + @Override + public JsonNode getJsonNode(UnirestInstance unirest) { + FoDUserGroupDescriptor userGroupDescriptor = FoDUserGroupHelper.getUserGroupDescriptor(unirest, userGroupResolver.getUserGroupNameOrId(), true); + unirest.delete(FoDUrls.USER_GROUP) + .routeParam("groupId", String.valueOf(userGroupDescriptor.getId())) + .asObject(JsonNode.class).getBody(); + return userGroupDescriptor.asObjectNode(); + } + + @Override + public JsonNode transformRecord(JsonNode record) { + return FoDUserGroupHelper.renameFields(record); + } + + @Override + public String getActionCommandResult() { + return "DELETED"; + } + + @Override + public boolean isSingular() { + return true; + } +} diff --git a/fcli-fod/src/main/java/com/fortify/cli/fod/user_group/cli/cmd/FoDUserGroupGetCommand.java b/fcli-fod/src/main/java/com/fortify/cli/fod/user_group/cli/cmd/FoDUserGroupGetCommand.java new file mode 100644 index 0000000000..d841658f95 --- /dev/null +++ b/fcli-fod/src/main/java/com/fortify/cli/fod/user_group/cli/cmd/FoDUserGroupGetCommand.java @@ -0,0 +1,61 @@ +/******************************************************************************* + * (c) Copyright 2020 Micro Focus or one of its affiliates + * + * 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 com.fortify.cli.fod.user_group.cli.cmd; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fortify.cli.common.output.cli.cmd.unirest.IUnirestJsonNodeSupplier; +import com.fortify.cli.common.output.spi.transform.IRecordTransformer; +import com.fortify.cli.fod.output.cli.AbstractFoDOutputCommand; +import com.fortify.cli.fod.output.mixin.FoDOutputHelperMixins; +import com.fortify.cli.fod.user_group.cli.mixin.FoDUserGroupResolverMixin; +import com.fortify.cli.fod.user_group.helper.FoDUserGroupHelper; +import io.micronaut.core.annotation.ReflectiveAccess; +import kong.unirest.UnirestInstance; +import lombok.Getter; +import picocli.CommandLine.Command; +import picocli.CommandLine.Mixin; + +@ReflectiveAccess +@Command(name = FoDOutputHelperMixins.Get.CMD_NAME) +public class FoDUserGroupGetCommand extends AbstractFoDOutputCommand implements IUnirestJsonNodeSupplier, IRecordTransformer { + @Getter @Mixin private FoDOutputHelperMixins.Get outputHelper; + @Mixin private FoDUserGroupResolverMixin.PositionalParameter userGroupResolver; + + @Override + public JsonNode getJsonNode(UnirestInstance unirest) { + return userGroupResolver.getUserGroupDescriptor(unirest).asJsonNode(); + } + + @Override + public JsonNode transformRecord(JsonNode record) { + return FoDUserGroupHelper.renameFields(record); + } + + @Override + public boolean isSingular() { + return true; + } + +} diff --git a/fcli-fod/src/main/java/com/fortify/cli/fod/user_group/cli/cmd/FoDUserGroupListCommand.java b/fcli-fod/src/main/java/com/fortify/cli/fod/user_group/cli/cmd/FoDUserGroupListCommand.java new file mode 100644 index 0000000000..080f3fde7e --- /dev/null +++ b/fcli-fod/src/main/java/com/fortify/cli/fod/user_group/cli/cmd/FoDUserGroupListCommand.java @@ -0,0 +1,67 @@ +/******************************************************************************* + * (c) Copyright 2020 Micro Focus or one of its affiliates + * + * 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 com.fortify.cli.fod.user_group.cli.cmd; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fortify.cli.common.output.cli.cmd.unirest.IUnirestBaseRequestSupplier; +import com.fortify.cli.common.output.spi.transform.IRecordTransformer; +import com.fortify.cli.fod.output.cli.AbstractFoDOutputCommand; +import com.fortify.cli.fod.output.mixin.FoDOutputHelperMixins; +import com.fortify.cli.fod.rest.FoDUrls; +import com.fortify.cli.fod.rest.query.FoDFilterParamGenerator; +import com.fortify.cli.fod.rest.query.FoDFiltersParamValueGenerators; +import com.fortify.cli.fod.rest.query.IFoDFilterParamGeneratorSupplier; +import com.fortify.cli.fod.user_group.helper.FoDUserGroupHelper; +import io.micronaut.core.annotation.ReflectiveAccess; +import kong.unirest.HttpRequest; +import kong.unirest.UnirestInstance; +import lombok.Getter; +import picocli.CommandLine.Command; +import picocli.CommandLine.Mixin; + +@ReflectiveAccess +@Command(name = FoDOutputHelperMixins.List.CMD_NAME) +public class FoDUserGroupListCommand extends AbstractFoDOutputCommand implements IUnirestBaseRequestSupplier, IRecordTransformer, IFoDFilterParamGeneratorSupplier { + @Getter @Mixin private FoDOutputHelperMixins.List outputHelper; + + @Getter private FoDFilterParamGenerator filterParamGenerator = new FoDFilterParamGenerator() + .add("groupId","groupId", FoDFiltersParamValueGenerators::plain) + .add("groupName","groupName", FoDFiltersParamValueGenerators::plain); + + @Override + public HttpRequest getBaseRequest(UnirestInstance unirest) { + return unirest.get(FoDUrls.USER_GROUPS); + } + + @Override + public JsonNode transformRecord(JsonNode record) { + return FoDUserGroupHelper.renameFields(record); + } + + @Override + public boolean isSingular() { + return false; + } +} diff --git a/fcli-fod/src/main/java/com/fortify/cli/fod/user_group/cli/cmd/FoDUserGroupUpdateCommand.java b/fcli-fod/src/main/java/com/fortify/cli/fod/user_group/cli/cmd/FoDUserGroupUpdateCommand.java new file mode 100644 index 0000000000..94528f4287 --- /dev/null +++ b/fcli-fod/src/main/java/com/fortify/cli/fod/user_group/cli/cmd/FoDUserGroupUpdateCommand.java @@ -0,0 +1,116 @@ +/******************************************************************************* + * (c) Copyright 2020 Micro Focus or one of its affiliates + * + * 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 com.fortify.cli.fod.user_group.cli.cmd; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fortify.cli.common.output.cli.cmd.unirest.IUnirestJsonNodeSupplier; +import com.fortify.cli.common.output.spi.transform.IActionCommandResultSupplier; +import com.fortify.cli.common.output.spi.transform.IRecordTransformer; +import com.fortify.cli.fod.app.helper.FoDAppHelper; +import com.fortify.cli.fod.output.cli.AbstractFoDOutputCommand; +import com.fortify.cli.fod.output.mixin.FoDOutputHelperMixins; +import com.fortify.cli.fod.user.helper.FoDUserHelper; +import com.fortify.cli.fod.user_group.cli.mixin.FoDUserGroupResolverMixin; +import com.fortify.cli.fod.user_group.helper.FoDUserGroupDescriptor; +import com.fortify.cli.fod.user_group.helper.FoDUserGroupHelper; +import com.fortify.cli.fod.user_group.helper.FoDUserGroupUpdateRequest; +import io.micronaut.core.annotation.ReflectiveAccess; +import io.micronaut.core.util.StringUtils; +import kong.unirest.UnirestInstance; +import lombok.Getter; +import picocli.CommandLine.Command; +import picocli.CommandLine.Mixin; +import picocli.CommandLine.Option; + +import java.util.ArrayList; + +@ReflectiveAccess +@Command(name = FoDOutputHelperMixins.Update.CMD_NAME) +public class FoDUserGroupUpdateCommand extends AbstractFoDOutputCommand implements IUnirestJsonNodeSupplier, IRecordTransformer, IActionCommandResultSupplier { + @Getter @Mixin private FoDOutputHelperMixins.Create outputHelper; + + @Mixin private FoDUserGroupResolverMixin.PositionalParameter userGroupResolver; + + @Option(names = {"--new-name"}) + private String newName; + @Option(names = {"--add-all-users"}) + private Boolean addAllUsers = false; + @Option(names = {"--remove-all-users"}) + private Boolean removeAllUsers = false; + @Option(names = {"--add-user"}, required = false, arity = "0..*") + private ArrayList addUsers; + @Option(names = {"--remove-user"}, required = false, arity = "0..*") + private ArrayList removeUsers; + @Option(names = {"--add-app", "--add-application"}, required = false, arity = "0..*") + private ArrayList addApplications; + @Option(names = {"--remove-app", "--remove-application"}, required = false, arity = "0..*") + private ArrayList removeApplications; + + @Override + public JsonNode getJsonNode(UnirestInstance unirest) { + validate(); + + FoDUserGroupDescriptor userGroupDescriptor = userGroupResolver.getUserGroupDescriptor(unirest); + FoDUserGroupUpdateRequest userGroupUpdateRequest = new FoDUserGroupUpdateRequest() + .setName(newName != null && StringUtils.isNotEmpty(newName) ? newName : userGroupDescriptor.getName()) + .setAddAllUsers(addAllUsers) + .setRemoveAllUsers(removeAllUsers); + + if (addUsers != null && addUsers.size() > 0) { + userGroupUpdateRequest.setAddUsers(FoDUserHelper.getUsersNode(unirest, addUsers)); + } + if (removeUsers != null && removeUsers.size() > 0) { + userGroupUpdateRequest.setRemoveUsers(FoDUserHelper.getUsersNode(unirest, removeUsers)); + } + if (addApplications != null && addApplications.size() > 0) { + userGroupUpdateRequest.setAddApplications(FoDAppHelper.getApplicationsNode(unirest, addApplications)); + } + if (removeApplications != null && removeApplications.size() > 0) { + userGroupUpdateRequest.setRemoveApplications(FoDAppHelper.getApplicationsNode(unirest, removeApplications)); + } + + return FoDUserGroupHelper.updateUserGroup(unirest, userGroupDescriptor.getId(), userGroupUpdateRequest).asJsonNode(); + } + + private void validate() { + + } + + @Override + public JsonNode transformRecord(JsonNode record) { + return FoDUserGroupHelper.renameFields(record); + } + + @Override + public String getActionCommandResult() { + return "CREATED"; + } + + @Override + public boolean isSingular() { + return true; + } + +} diff --git a/fcli-fod/src/main/java/com/fortify/cli/fod/user_group/cli/mixin/FoDUserGroupResolverMixin.java b/fcli-fod/src/main/java/com/fortify/cli/fod/user_group/cli/mixin/FoDUserGroupResolverMixin.java new file mode 100644 index 0000000000..d294fb84af --- /dev/null +++ b/fcli-fod/src/main/java/com/fortify/cli/fod/user_group/cli/mixin/FoDUserGroupResolverMixin.java @@ -0,0 +1,74 @@ +/******************************************************************************* + * (c) Copyright 2020 Micro Focus or one of its affiliates + * + * 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 com.fortify.cli.fod.user_group.cli.mixin; + +import com.fortify.cli.common.variable.AbstractPredefinedVariableResolverMixin; +import com.fortify.cli.fod.user_group.cli.cmd.FoDUserGroupCommands; +import com.fortify.cli.fod.user_group.helper.FoDUserGroupDescriptor; +import com.fortify.cli.fod.user_group.helper.FoDUserGroupHelper; +import io.micronaut.core.annotation.ReflectiveAccess; +import kong.unirest.UnirestInstance; +import lombok.Getter; +import picocli.CommandLine.Option; +import picocli.CommandLine.Parameters; + +public class FoDUserGroupResolverMixin { + @ReflectiveAccess + public static abstract class AbstractFoDUserGroupResolverMixin extends AbstractPredefinedVariableResolverMixin { + public abstract String getUserGroupNameOrId(); + + public FoDUserGroupDescriptor getUserGroupDescriptor(UnirestInstance unirest, String... fields){ + return FoDUserGroupHelper.getUserGroupDescriptor(unirest, resolvePredefinedVariable(getUserGroupNameOrId()), true); + } + + public String getGroupId(UnirestInstance unirest) { + return getUserGroupDescriptor(unirest, "groupId").getId().toString(); + } + + @Override + protected Class getPredefinedVariableClass() { + return FoDUserGroupCommands.class; + } + } + + @ReflectiveAccess + public static class RequiredOption extends AbstractFoDUserGroupResolverMixin { + @Option(names = {"--group"}, required = true, descriptionKey = "GroupMixin") + @Getter private String userGroupNameOrId; + } + + @ReflectiveAccess + public static class OptionalOption extends AbstractFoDUserGroupResolverMixin { + @Option(names = {"--group"}, required = false, descriptionKey = "GroupMixin") + @Getter private String userGroupNameOrId; + } + + @ReflectiveAccess + public static class PositionalParameter extends AbstractFoDUserGroupResolverMixin { + @Parameters(index = "0", arity = "1", descriptionKey = "GroupMixin") + @Getter private String userGroupNameOrId; + } +} \ No newline at end of file diff --git a/fcli-fod/src/main/java/com/fortify/cli/fod/user_group/helper/FoDUserGroupAppAccessRequest.java b/fcli-fod/src/main/java/com/fortify/cli/fod/user_group/helper/FoDUserGroupAppAccessRequest.java new file mode 100644 index 0000000000..4ef37ee4e3 --- /dev/null +++ b/fcli-fod/src/main/java/com/fortify/cli/fod/user_group/helper/FoDUserGroupAppAccessRequest.java @@ -0,0 +1,42 @@ +/******************************************************************************* + * (c) Copyright 2020 Micro Focus or one of its affiliates + * + * 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 com.fortify.cli.fod.user_group.helper; + +import io.micronaut.core.annotation.ReflectiveAccess; +import lombok.Getter; +import lombok.ToString; + +@ReflectiveAccess +@Getter +@ToString +public class FoDUserGroupAppAccessRequest { + private Integer applicationId; + + public FoDUserGroupAppAccessRequest setApplicationId(Integer id) { + this.applicationId = id; + return this; + } + +} diff --git a/fcli-fod/src/main/java/com/fortify/cli/fod/user_group/helper/FoDUserGroupCreateRequest.java b/fcli-fod/src/main/java/com/fortify/cli/fod/user_group/helper/FoDUserGroupCreateRequest.java new file mode 100644 index 0000000000..78ae138643 --- /dev/null +++ b/fcli-fod/src/main/java/com/fortify/cli/fod/user_group/helper/FoDUserGroupCreateRequest.java @@ -0,0 +1,62 @@ +/******************************************************************************* + * (c) Copyright 2020 Micro Focus or one of its affiliates + * + * 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 com.fortify.cli.fod.user_group.helper; + +import com.fasterxml.jackson.databind.JsonNode; +import io.micronaut.core.annotation.ReflectiveAccess; +import lombok.Getter; +import lombok.ToString; + +@ReflectiveAccess +@Getter +@ToString +public class FoDUserGroupCreateRequest { + private String name; + private Boolean addAllUsers = false; + private JsonNode users; + + private JsonNode applications; + + public FoDUserGroupCreateRequest setName(String name) { + this.name = name; + return this; + } + + public FoDUserGroupCreateRequest setAddAllUsers(Boolean addAllUsers) { + this.addAllUsers = addAllUsers; + return this; + } + + public FoDUserGroupCreateRequest setUsers(JsonNode ids) { + this.users = ids; + return this; + } + + public FoDUserGroupCreateRequest setApplications(JsonNode ids) { + this.applications = ids; + return this; + } + +} diff --git a/fcli-fod/src/main/java/com/fortify/cli/fod/user_group/helper/FoDUserGroupDescriptor.java b/fcli-fod/src/main/java/com/fortify/cli/fod/user_group/helper/FoDUserGroupDescriptor.java index 126f3a1f73..57fdd57867 100644 --- a/fcli-fod/src/main/java/com/fortify/cli/fod/user_group/helper/FoDUserGroupDescriptor.java +++ b/fcli-fod/src/main/java/com/fortify/cli/fod/user_group/helper/FoDUserGroupDescriptor.java @@ -24,7 +24,6 @@ ******************************************************************************/ package com.fortify.cli.fod.user_group.helper; -import com.fasterxml.jackson.annotation.JsonProperty; import com.fortify.cli.common.json.JsonNodeHolder; import io.micronaut.core.annotation.ReflectiveAccess; import lombok.Data; @@ -34,7 +33,7 @@ @Data @EqualsAndHashCode(callSuper = true) public class FoDUserGroupDescriptor extends JsonNodeHolder { - private String id; + private Integer id; private String name; private Integer assignedUsersCount; private Integer assignedApplicationsCount; diff --git a/fcli-fod/src/main/java/com/fortify/cli/fod/user_group/helper/FoDUserGroupHelper.java b/fcli-fod/src/main/java/com/fortify/cli/fod/user_group/helper/FoDUserGroupHelper.java index d87dc4aac0..e9151d752e 100644 --- a/fcli-fod/src/main/java/com/fortify/cli/fod/user_group/helper/FoDUserGroupHelper.java +++ b/fcli-fod/src/main/java/com/fortify/cli/fod/user_group/helper/FoDUserGroupHelper.java @@ -25,16 +25,33 @@ package com.fortify.cli.fod.user_group.helper; import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ArrayNode; import com.fasterxml.jackson.databind.node.ObjectNode; import com.fortify.cli.common.json.JsonHelper; +import com.fortify.cli.common.output.transform.fields.RenameFieldsTransformer; +import com.fortify.cli.fod.app.helper.FoDAppDescriptor; +import com.fortify.cli.fod.app.helper.FoDAppHelper; import com.fortify.cli.fod.rest.FoDUrls; +import com.fortify.cli.fod.user.helper.FoDUserDescriptor; +import com.fortify.cli.fod.user.helper.FoDUserHelper; +import com.fortify.cli.fod.util.FoDEnums; import kong.unirest.GetRequest; import kong.unirest.UnirestInstance; +import lombok.Getter; import javax.validation.ValidationException; +import java.util.ArrayList; public class FoDUserGroupHelper { - public static final FoDUserGroupDescriptor getUserGroup(UnirestInstance unirestInstance, String userGroupNameOrId, boolean failIfNotFound) { + @Getter + private static ObjectMapper objectMapper = new ObjectMapper(); + + public static final JsonNode renameFields(JsonNode record) { + return new RenameFieldsTransformer(new String[]{}).transform(record); + } + + public static final FoDUserGroupDescriptor getUserGroupDescriptor(UnirestInstance unirestInstance, String userGroupNameOrId, boolean failIfNotFound) { GetRequest request = unirestInstance.get(FoDUrls.USER_GROUPS); try { int attrId = Integer.parseInt(userGroupNameOrId); @@ -50,4 +67,138 @@ public static final FoDUserGroupDescriptor getUserGroup(UnirestInstance unirestI } return attr.size() == 0 ? null : JsonHelper.treeToValue(attr.get(0), FoDUserGroupDescriptor.class); } + + public static final FoDUserGroupDescriptor getUserGroupDescriptorById(UnirestInstance unirest, String groupId, boolean failIfNotFound) { + GetRequest request = unirest.get(FoDUrls.USER_GROUP).routeParam("groupId", groupId); + JsonNode group = request.asObject(ObjectNode.class).getBody(); + if (failIfNotFound && group.get("name").asText().isEmpty()) { + throw new ValidationException("No user group for id: " + groupId); + } + return getDescriptor(group); + } + + public static final FoDUserGroupDescriptor createUserGroup(UnirestInstance unirest, FoDUserGroupCreateRequest userGroupCreateRequest) { + ObjectNode body = objectMapper.valueToTree(userGroupCreateRequest); + JsonNode response = unirest.post(FoDUrls.USER_GROUPS) + .body(body).asObject(JsonNode.class).getBody(); + FoDUserGroupDescriptor descriptor = JsonHelper.treeToValue(response, FoDUserGroupDescriptor.class); + String groupId = String.valueOf(descriptor.getId()); + // add any users specified to group + ArrayList userstoUpdate = objectMapper.convertValue(userGroupCreateRequest.getUsers(), ArrayList.class); + if (userGroupCreateRequest.getUsers() != null && userGroupCreateRequest.getUsers().size() > 0) { + for (Integer userId: userstoUpdate) { + FoDUserGroupHelper.updateUserGroupMembership(unirest, String.valueOf(userId), groupId, FoDEnums.UserGroupMembershipAction.Add); + } + } + // add group to any applications specified + ArrayList appsToUpdate = objectMapper.convertValue(userGroupCreateRequest.getApplications(), ArrayList.class); + if (userGroupCreateRequest.getApplications() != null && userGroupCreateRequest.getApplications().size() > 0) { + for (Integer appId: appsToUpdate) { + FoDUserGroupHelper.updateUserGroupApplicationAccess(unirest, String.valueOf(groupId), String.valueOf(appId), FoDEnums.UserGroupApplicationAccessAction.Add); + } + } + return FoDUserGroupHelper.getUserGroupDescriptor(unirest, groupId, true); + } + + public static final FoDUserGroupDescriptor updateUserGroup(UnirestInstance unirest, Integer groupId, FoDUserGroupUpdateRequest userGroupUpdateRequest) { + ObjectNode body = objectMapper.valueToTree(userGroupUpdateRequest); + JsonNode response = unirest.put(FoDUrls.USER_GROUP) + .routeParam("groupId", String.valueOf(groupId)) + .body(body).asObject(JsonNode.class).getBody(); + // add any users specified to group + ArrayList userstoUpdate = objectMapper.convertValue(userGroupUpdateRequest.getAddUsers(), ArrayList.class); + if (userGroupUpdateRequest.getAddUsers() != null && userGroupUpdateRequest.getAddUsers().size() > 0) { + for (Integer userId: userstoUpdate) { + FoDUserGroupHelper.updateUserGroupMembership(unirest, String.valueOf(userId), String.valueOf(groupId), FoDEnums.UserGroupMembershipAction.Add); + } + } + // remove any users specified from group + userstoUpdate = objectMapper.convertValue(userGroupUpdateRequest.getRemoveUsers(), ArrayList.class); + if (userGroupUpdateRequest.getRemoveUsers() != null && userGroupUpdateRequest.getRemoveUsers().size() > 0) { + for (Integer userId: userstoUpdate) { + FoDUserGroupHelper.updateUserGroupMembership(unirest, String.valueOf(userId), String.valueOf(groupId), FoDEnums.UserGroupMembershipAction.Remove); + } + } + // add group to any applications specified + ArrayList appsToUpdate = objectMapper.convertValue(userGroupUpdateRequest.getAddApplications(), ArrayList.class); + if (userGroupUpdateRequest.getAddApplications() != null && userGroupUpdateRequest.getAddApplications().size() > 0) { + for (Integer appId: appsToUpdate) { + FoDUserGroupHelper.updateUserGroupApplicationAccess(unirest, String.valueOf(groupId), String.valueOf(appId), FoDEnums.UserGroupApplicationAccessAction.Add); + } + } + // remove group from any applications specified + appsToUpdate = objectMapper.convertValue(userGroupUpdateRequest.getRemoveApplications(), ArrayList.class); + if (userGroupUpdateRequest.getRemoveApplications() != null && userGroupUpdateRequest.getRemoveApplications().size() > 0) { + for (Integer appId: appsToUpdate) { + FoDUserGroupHelper.updateUserGroupApplicationAccess(unirest, String.valueOf(groupId), String.valueOf(appId), FoDEnums.UserGroupApplicationAccessAction.Remove); + } + } + return getUserGroupDescriptor(unirest, String.valueOf(groupId), true); + } + + public static final FoDUserGroupDescriptor updateUserGroupMembership(UnirestInstance unirest, String userNameOrId, String userGroupNameOrId, + FoDEnums.UserGroupMembershipAction action) { + FoDUserDescriptor userDescriptor = FoDUserHelper.getUserDescriptor(unirest, userNameOrId, true); + FoDUserGroupDescriptor userGroupDescriptor = FoDUserGroupHelper.getUserGroupDescriptor(unirest, userGroupNameOrId, true); + ArrayList userIds = new ArrayList<>(); + userIds.add(userDescriptor.getUserId()); + FoDUserGroupMembersRequest userGroupMembersRequest = new FoDUserGroupMembersRequest(); + if (action.equals(FoDEnums.UserGroupMembershipAction.Add)) { + userGroupMembersRequest.setRemoveUsers(new ArrayList<>()); + userGroupMembersRequest.setAddUsers(userIds); + } else if (action.equals(FoDEnums.UserGroupMembershipAction.Remove)) { + userGroupMembersRequest.setRemoveUsers(userIds); + userGroupMembersRequest.setAddUsers(new ArrayList<>()); + } else { + throw new ValidationException("Invalid action specified when updating users group membership"); + } + ObjectNode body = objectMapper.valueToTree(userGroupMembersRequest); + JsonNode response = unirest.patch(FoDUrls.USER_GROUP_MEMBERS).routeParam("groupId", String.valueOf(userGroupDescriptor.getId())) + .body(body).asObject(JsonNode.class).getBody(); + return getUserGroupDescriptor(unirest, String.valueOf(userGroupDescriptor.getId()), true); + } + + public static final FoDUserGroupDescriptor updateUserGroupApplicationAccess(UnirestInstance unirest, String userGroupOrId, String appNameOrId, + FoDEnums.UserGroupApplicationAccessAction action) { + FoDUserGroupDescriptor userGroupDescriptor = FoDUserGroupHelper.getUserGroupDescriptor(unirest, userGroupOrId, true); + FoDAppDescriptor appDescriptor = FoDAppHelper.getAppDescriptor(unirest, appNameOrId, true); + if (action.equals(FoDEnums.UserGroupApplicationAccessAction.Add)) { + FoDUserGroupAppAccessRequest appAccessRequest = new FoDUserGroupAppAccessRequest() + .setApplicationId(appDescriptor.getApplicationId()); + ObjectNode body = objectMapper.valueToTree(appAccessRequest); + unirest.post(FoDUrls.USER_GROUP_APPLICATION_ACCESS).routeParam("userGroupId", String.valueOf(userGroupDescriptor.getId())) + .body(body).asEmpty(); + } else if (action.equals(FoDEnums.UserGroupApplicationAccessAction.Remove)) { + unirest.delete(FoDUrls.USER_GROUP_APPLICATION_ACCESS_DELETE) + .routeParam("userGroupId", String.valueOf(userGroupDescriptor.getId())) + .routeParam("applicationId", String.valueOf(appDescriptor.getApplicationId())) + .asEmpty(); + } else { + throw new ValidationException("Invalid action specified when updating user group application access"); + } + return userGroupDescriptor; + } + + public static JsonNode getUserGroupsNode(ArrayList userGroups) { + ArrayNode userGroupArray = objectMapper.createArrayNode(); + if (userGroups == null || userGroups.isEmpty()) return userGroupArray; + for (Integer ug : userGroups) { + userGroupArray.add(ug); + } + return userGroupArray; + } + + public static JsonNode getUserGroupsNode(UnirestInstance unirest, ArrayList userGroups) { + ArrayNode userGroupArray = getObjectMapper().createArrayNode(); + if (userGroups == null || userGroups.isEmpty()) return userGroupArray; + for (String ug : userGroups) { + FoDUserGroupDescriptor userGroupDescriptor = FoDUserGroupHelper.getUserGroupDescriptor(unirest, ug, true); + userGroupArray.add(userGroupDescriptor.getId()); + } + return userGroupArray; + } + + private static final FoDUserGroupDescriptor getDescriptor(JsonNode node) { + return JsonHelper.treeToValue(node, FoDUserGroupDescriptor.class); + } } diff --git a/fcli-fod/src/main/java/com/fortify/cli/fod/user_group/helper/FoDUserGroupMembersRequest.java b/fcli-fod/src/main/java/com/fortify/cli/fod/user_group/helper/FoDUserGroupMembersRequest.java new file mode 100644 index 0000000000..9d5dfb5b06 --- /dev/null +++ b/fcli-fod/src/main/java/com/fortify/cli/fod/user_group/helper/FoDUserGroupMembersRequest.java @@ -0,0 +1,50 @@ +/******************************************************************************* + * (c) Copyright 2020 Micro Focus or one of its affiliates + * + * 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 com.fortify.cli.fod.user_group.helper; + +import io.micronaut.core.annotation.ReflectiveAccess; +import lombok.Getter; +import lombok.ToString; + +import java.util.ArrayList; + +@ReflectiveAccess +@Getter +@ToString +public class FoDUserGroupMembersRequest { + private ArrayList removeUsers; + private ArrayList addUsers; + + public FoDUserGroupMembersRequest setRemoveUsers(ArrayList ids) { + this.removeUsers = ids; + return this; + } + + public FoDUserGroupMembersRequest setAddUsers(ArrayList ids) { + this.addUsers = ids; + return this; + } + +} diff --git a/fcli-fod/src/main/java/com/fortify/cli/fod/user_group/helper/FoDUserGroupUpdateRequest.java b/fcli-fod/src/main/java/com/fortify/cli/fod/user_group/helper/FoDUserGroupUpdateRequest.java new file mode 100644 index 0000000000..4013d89a19 --- /dev/null +++ b/fcli-fod/src/main/java/com/fortify/cli/fod/user_group/helper/FoDUserGroupUpdateRequest.java @@ -0,0 +1,80 @@ +/******************************************************************************* + * (c) Copyright 2020 Micro Focus or one of its affiliates + * + * 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 com.fortify.cli.fod.user_group.helper; + +import com.fasterxml.jackson.databind.JsonNode; +import io.micronaut.core.annotation.ReflectiveAccess; +import lombok.Getter; +import lombok.ToString; + +@ReflectiveAccess +@Getter +@ToString +public class FoDUserGroupUpdateRequest { + private String name; + private Boolean addAllUsers = false; + private Boolean removeAllUsers = false; + private JsonNode addUsers; + private JsonNode removeUsers; + private JsonNode addApplications; + private JsonNode removeApplications; + + public FoDUserGroupUpdateRequest setName(String name) { + this.name = name; + return this; + } + + public FoDUserGroupUpdateRequest setAddAllUsers(Boolean addAllUsers) { + this.addAllUsers = addAllUsers; + return this; + } + + public FoDUserGroupUpdateRequest setRemoveAllUsers(Boolean removeAllUsers) { + this.removeAllUsers = removeAllUsers; + return this; + } + + public FoDUserGroupUpdateRequest setAddUsers(JsonNode ids) { + this.addUsers = ids; + return this; + } + + public FoDUserGroupUpdateRequest setRemoveUsers(JsonNode ids) { + this.removeUsers = ids; + return this; + } + + public FoDUserGroupUpdateRequest setAddApplications(JsonNode ids) { + this.addApplications = ids; + return this; + } + + public FoDUserGroupUpdateRequest setRemoveApplications(JsonNode ids) { + this.removeApplications = ids; + return this; + } + + +} diff --git a/fcli-fod/src/main/java/com/fortify/cli/fod/util/FoDEnums.java b/fcli-fod/src/main/java/com/fortify/cli/fod/util/FoDEnums.java index 36aac81450..1f49266110 100644 --- a/fcli-fod/src/main/java/com/fortify/cli/fod/util/FoDEnums.java +++ b/fcli-fod/src/main/java/com/fortify/cli/fod/util/FoDEnums.java @@ -387,4 +387,20 @@ public String getValue() { } } + + public enum UserApplicationAccessAction { + Add, Remove + } + + public enum UserGroupApplicationAccessAction { + Add, Remove + } + + public enum UserGroupMembershipAction { + Add, Remove + } + + + + } diff --git a/fcli-fod/src/main/resources/com/fortify/cli/fod/i18n/FoDMessages.properties b/fcli-fod/src/main/resources/com/fortify/cli/fod/i18n/FoDMessages.properties index 1906de665d..f86cb5910d 100644 --- a/fcli-fod/src/main/resources/com/fortify/cli/fod/i18n/FoDMessages.properties +++ b/fcli-fod/src/main/resources/com/fortify/cli/fod/i18n/FoDMessages.properties @@ -18,6 +18,8 @@ RemediationScanPreferenceTypeMixin = The remediation scan type to use. Valid val AppMicroserviceUpdateMixin = Application microservice name. ApplicationMicroserviceReleaseMixin = Application release id or :: name. SbomFormatMixin = The SBOM format to import. If empty Cyclone DX format is assumed. +UserMixin = User id or username. +GroupMixin = Group id or name. # Shared options scan-id's[0] = One or more scan id's; supports '-' to reference a scan id previously stored using '--store -' @@ -253,6 +255,75 @@ fcli.fod.oss-scan.import.file = Absolute path of the (JSON) SBOM file to upload. fcli.fod.oss-scan.import.chunk-size = Fragment size (in bytes) for file uploads. Default is 8Mb. +### For the "fod user" command ### +fcli.fod.user.usage.header = Commands for interacting with users on Fortify on Demand (FoD). + +# For the "fod user create" command +fcli.fod.user.create.usage.header = Create a new user on Fortify on Demand (FoD). +fcli.fod.user.create.user-name = The username of the user. +fcli.fod.user.create.email = The email address of the user. +fcli.fod.user.create.firstname = The first name of the user. +fcli.fod.user.create.lastname = The last name of the user. +fcli.fod.user.create.phone = The phone number of the user. +fcli.fod.user.create.role = The id or name of the role the user should be given. +fcli.fod.user.create.group = The id or name of a group the user should be added to. +fcli.fod.user.create.application = The id or name of an application to give the user permission to. + +# For the "fod user delete" command +fcli.fod.user.delete.usage.header = Delete a user from Fortify on Demand (FoD). + +# For the "fod user list" command +fcli.fod.user.list.usage.header = List users on Fortify on Demand (FoD). + +# For the "fod user get" command +fcli.fod.user.get.usage.header = Get user on Fortify on Demand (FoD). + +# For the "fod user update" command +fcli.fod.user.update.usage.header = Update a user on Fortify on Demand (FoD). +fcli.fod.user.update.email = The updated email address of the user. +fcli.fod.user.update.firstname = Updated first name of the user. +fcli.fod.user.update.lastname = Updated last name of the user. +fcli.fod.user.update.phone = Updated phone number of the user. +fcli.fod.user.update.role = Updated id or name of the role the user should be given. +fcli.fod.user.update.password-never-expires = Set a flag to indicate that the users password will never expire. +fcli.fod.user.update.suspended = Suspend the user. +fcli.fod.user.update.must-change = Set a flag to indicate that users password must be changed on next login. +fcli.fod.user.update.add-group - The id or name of a group the user should be added to. +fcli.fod.user.update.remove-group - The id or name of a group the user should be removed from. +fcli.fod.user.update.add-application - The id or name of an application the user should be added to. +fcli.fod.user.update.remove-application - The id or name of an application the user should be removed from. + + +### For the "fod user-group" command ### +fcli.fod.user-group.usage.header = Commands for interacting with user groups on Fortify on Demand (FoD). + +# For the "fod user-group create" command +fcli.fod.user-group.create.usage.header = Create a new user group on Fortify on Demand (FoD). +fcli.fod.user-group.create.group-name = The name of the user group. +fcli.fod.user-group.create.add-all-users = Add all tenant users to the user group. +fcli.fod.user-group.create.user = The id or name of a user to add to the user group. +fcli.fod.user-group.create.application = The id or name of an application to give the user group permission to. + +# For the "fod user-group delete" command +fcli.fod.user-group.delete.usage.header = Delete a user group from Fortify on Demand (FoD). + +# For the "fod user-group list" command +fcli.fod.user-group.list.usage.header = List user groups on Fortify on Demand (FoD). + +# For the "fod user-group get" command +fcli.fod.user-group.get.usage.header = Get user group on Fortify on Demand (FoD). + +# For the "fod user-group update" command +fcli.fod.user-group.update.usage.header = Update a user group on Fortify on Demand (FoD). +fcli.fod.user-group.update.new-name = The updated name of the user group. +fcli.fod.user-group.update.add-all-users = Add all tenant users to the user group. +fcli.fod.user-group.update.remove-all-users = Remove all tenant users to the user group. +fcli.fod.user-group.update.add-user = The id or name of a user to add to the user group. +fcli.fod.user-group.update.remove-user = The id or name of a user to remove from the user group. +fcli.fod.user-group.update.add-application = The id or name of an application to give the user group permission to. +fcli.fod.user-group.update.remove-application = The id or name of an application to remove the user group permission to. + + ### For the "fod session" command ### fcli.fod.session.usage.header = Commands to manage Fortify on Demand (FoD) sessions. @@ -361,4 +432,21 @@ fcli.fod.oss-scan.output.header.completedDateTime = Completed fcli.fod.oss-scan.output.header.scanMethodTypeName = Scan Method fcli.fod.oss-scan.output.header.applicationName = Application fcli.fod.oss-scan.output.header.microserviceName = Microservice -fcli.fod.oss-scan.output.header.releaseName = Release \ No newline at end of file +fcli.fod.oss-scan.output.header.releaseName = Release + +fcli.fod.user.output.table.options = userId,userName,firstName,lastName,email,roleName +fcli.fod.user.update.output.table.options = userId,userName,firstName,lastName,email,roleName +fcli.fod.user.delete.output.table.options = userId,userName +fcli.fod.user.output.header.userId = Id +fcli.fod.user.output.header.userName = Username +fcli.fod.user.output.header.firstName = First Name +fcli.fod.user.output.header.lastName = Last Name +fcli.fod.user.output.header.roleName = Role + +fcli.fod.user-group.output.table.options = id,name,assignedUsersCount,assignedApplicationsCount +fcli.fod.user-group.update.output.table.options = id,name,assignedUsersCount,assignedApplicationsCount +fcli.fod.user-group.delete.output.table.options = id,name +fcli.fod.user-group.output.header.id = Id +fcli.fod.user-group.output.header.name = Name +fcli.fod.user-group.output.header.assignedUsersCount = Assigned Users +fcli.fod.user-group.output.header.assignedApplicationsCount = Assigned Applications