From 9b6eac64696b217ce3e847aeeb4d358b20842102 Mon Sep 17 00:00:00 2001 From: emanipravallika Date: Thu, 12 Oct 2023 11:58:28 +0530 Subject: [PATCH 1/2] OP-20978: Feature: New Gate Api for fetching userDetails along with cloudAccounts --- docker_build/gate.yml | 2 +- .../gate/controllers/AuthController.groovy | 25 +++++++ .../gate/services/UserInfoService.groovy | 74 +++++++++++++++++++ .../gate/model/UserInfoDetailsModel.java | 36 +++++++++ 4 files changed, 136 insertions(+), 1 deletion(-) create mode 100644 gate-web/src/main/groovy/com/netflix/spinnaker/gate/services/UserInfoService.groovy create mode 100644 gate-web/src/main/java/com/opsmx/spinnaker/gate/model/UserInfoDetailsModel.java diff --git a/docker_build/gate.yml b/docker_build/gate.yml index 9d71b84e80..634730f228 100644 --- a/docker_build/gate.yml +++ b/docker_build/gate.yml @@ -1,6 +1,6 @@ services: opsmx: - baseUrl: http://oes-api:8085 + baseUrl: http://localhost:8085 enabled: true autopilot: baseUrl: http://localhost:8090 diff --git a/gate-web/src/main/groovy/com/netflix/spinnaker/gate/controllers/AuthController.groovy b/gate-web/src/main/groovy/com/netflix/spinnaker/gate/controllers/AuthController.groovy index 353aba1e03..83e4c4e950 100644 --- a/gate-web/src/main/groovy/com/netflix/spinnaker/gate/controllers/AuthController.groovy +++ b/gate-web/src/main/groovy/com/netflix/spinnaker/gate/controllers/AuthController.groovy @@ -18,6 +18,8 @@ package com.netflix.spinnaker.gate.controllers import com.netflix.spinnaker.gate.security.SpinnakerUser import com.netflix.spinnaker.gate.services.PermissionService +import com.netflix.spinnaker.gate.services.UserInfoService +import com.netflix.spinnaker.gate.services.internal.OpsmxOesService import com.netflix.spinnaker.security.AuthenticatedRequest import com.netflix.spinnaker.security.User import groovy.util.logging.Slf4j @@ -58,6 +60,12 @@ class AuthController { @Autowired PermissionService permissionService + @Autowired + UserInfoService userInfoService + + @Autowired + OpsmxOesService opsmxOesService + @Autowired AuthController(@Value('${services.deck.base-url:}') URL deckBaseUrl, @Value('${services.deck.redirect-host-pattern:#{null}}') String redirectHostPattern) { @@ -160,4 +168,21 @@ class AuthController { AuthenticatedRequest.getSpinnakerUser().orElse("anonymous") ) } + + @ApiOperation(value = "Get user Details") + @RequestMapping(value = "/userInfo", method = RequestMethod.GET) + Object userInfo(@ApiIgnore @SpinnakerUser User user) { + if (!user) { + throw new Exception("UnAuthorized User") + } + def fiatRoles = permissionService.getRoles(user.username)?.collect{ it.name } + if (fiatRoles) { + user.roles = fiatRoles + } + def response = opsmxOesService.getOesResponse5( + "accountsConfig", "v3", "spinnaker", "cloudProviderAccount", false, false) + def userInfo = userInfoService.getAllInfoOfUser(user, response) + log.info("UserInfo: {}", userInfo) + return userInfo + } } diff --git a/gate-web/src/main/groovy/com/netflix/spinnaker/gate/services/UserInfoService.groovy b/gate-web/src/main/groovy/com/netflix/spinnaker/gate/services/UserInfoService.groovy new file mode 100644 index 0000000000..ee8d403051 --- /dev/null +++ b/gate-web/src/main/groovy/com/netflix/spinnaker/gate/services/UserInfoService.groovy @@ -0,0 +1,74 @@ +/* + * Copyright 2023 Netflix, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.netflix.spinnaker.gate.services + +import com.google.gson.Gson +import com.google.gson.JsonParser +import com.opsmx.spinnaker.gate.model.UserInfoDetailsModel +import com.netflix.spinnaker.gate.services.internal.OpsmxOesService +import com.netflix.spinnaker.security.User +import groovy.util.logging.Slf4j +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.stereotype.Service + +@Slf4j +@Service +class UserInfoService { + + @Autowired + OpsmxOesService opsmxOesService + + Gson gson = new Gson() + + Object getAllInfoOfUser(User user, Object response) throws Exception { + + UserInfoDetailsModel userInfoDetails = new UserInfoDetailsModel() + try { + log.info("CloudProviderAccounts: {}", response) + def inputStr = gson.toJson(response) + def extractedCloudAccounts = JsonParser.parseString(inputStr).getAsJsonArray() + + /*def cloudAccounts = extractedCloudAccounts.collect { + def accountType = it.getAsJsonPrimitive("accountType").getAsString() + def name = it.getAsJsonPrimitive("name").getAsString() + "cloudProvider: " + accountType + " , " + "accountName: " + name + } +*/ + def cloudAccounts = extractedCloudAccounts.collect { accountJson -> + def accountType = accountJson.getAsJsonPrimitive("accountType").getAsString() + def name = accountJson.getAsJsonPrimitive("name").getAsString() + + def cloudAccount = [cloudProvider: accountType, accountName: name] + cloudAccount + } + + log.info("CLoudAccounts: {}", cloudAccounts) + + userInfoDetails.cloudAccounts = cloudAccounts + userInfoDetails.userName = user.username + userInfoDetails.firstName = user.firstName + userInfoDetails.lastName = user.lastName + userInfoDetails.userMailId = user.email + userInfoDetails.userRoles = user.roles + + } catch (Exception e) { + e.printStackTrace() + } + + return userInfoDetails + } +} diff --git a/gate-web/src/main/java/com/opsmx/spinnaker/gate/model/UserInfoDetailsModel.java b/gate-web/src/main/java/com/opsmx/spinnaker/gate/model/UserInfoDetailsModel.java new file mode 100644 index 0000000000..d44d7a6268 --- /dev/null +++ b/gate-web/src/main/java/com/opsmx/spinnaker/gate/model/UserInfoDetailsModel.java @@ -0,0 +1,36 @@ +/* + * Copyright 2023 Netflix, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.opsmx.spinnaker.gate.model; + +import com.fasterxml.jackson.annotation.JsonInclude; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import lombok.Data; + +@Data +@JsonInclude +public class UserInfoDetailsModel { + + private String userName; + private String firstName; + private String lastName; + private String userMailId; + + private Collection userRoles = new ArrayList<>(); + private List cloudAccounts = new ArrayList<>(); +} From 5a41add0e8a3408752f3c04ef93af331415c51fa Mon Sep 17 00:00:00 2001 From: emanipravallika Date: Thu, 12 Oct 2023 16:03:03 +0530 Subject: [PATCH 2/2] OP-20978: Removed commented code. --- .../gate/controllers/AuthController.groovy | 7 ++----- .../gate/services/UserInfoService.groovy | 20 +++---------------- 2 files changed, 5 insertions(+), 22 deletions(-) diff --git a/gate-web/src/main/groovy/com/netflix/spinnaker/gate/controllers/AuthController.groovy b/gate-web/src/main/groovy/com/netflix/spinnaker/gate/controllers/AuthController.groovy index 83e4c4e950..5eb316e41f 100644 --- a/gate-web/src/main/groovy/com/netflix/spinnaker/gate/controllers/AuthController.groovy +++ b/gate-web/src/main/groovy/com/netflix/spinnaker/gate/controllers/AuthController.groovy @@ -24,7 +24,6 @@ import com.netflix.spinnaker.security.AuthenticatedRequest import com.netflix.spinnaker.security.User import groovy.util.logging.Slf4j import io.swagger.annotations.ApiOperation -import org.apache.commons.lang3.exception.ExceptionUtils import org.springframework.beans.factory.annotation.Autowired import org.springframework.beans.factory.annotation.Value import org.springframework.security.access.prepost.PreAuthorize @@ -169,7 +168,7 @@ class AuthController { ) } - @ApiOperation(value = "Get user Details") + @ApiOperation(value = "Get user Details with cloudAccounts") @RequestMapping(value = "/userInfo", method = RequestMethod.GET) Object userInfo(@ApiIgnore @SpinnakerUser User user) { if (!user) { @@ -181,8 +180,6 @@ class AuthController { } def response = opsmxOesService.getOesResponse5( "accountsConfig", "v3", "spinnaker", "cloudProviderAccount", false, false) - def userInfo = userInfoService.getAllInfoOfUser(user, response) - log.info("UserInfo: {}", userInfo) - return userInfo + return userInfoService.getAllInfoOfUser(user, response) } } diff --git a/gate-web/src/main/groovy/com/netflix/spinnaker/gate/services/UserInfoService.groovy b/gate-web/src/main/groovy/com/netflix/spinnaker/gate/services/UserInfoService.groovy index ee8d403051..1ef04bcfa1 100644 --- a/gate-web/src/main/groovy/com/netflix/spinnaker/gate/services/UserInfoService.groovy +++ b/gate-web/src/main/groovy/com/netflix/spinnaker/gate/services/UserInfoService.groovy @@ -18,45 +18,32 @@ package com.netflix.spinnaker.gate.services import com.google.gson.Gson import com.google.gson.JsonParser -import com.opsmx.spinnaker.gate.model.UserInfoDetailsModel -import com.netflix.spinnaker.gate.services.internal.OpsmxOesService import com.netflix.spinnaker.security.User +import com.opsmx.spinnaker.gate.model.UserInfoDetailsModel import groovy.util.logging.Slf4j -import org.springframework.beans.factory.annotation.Autowired import org.springframework.stereotype.Service @Slf4j @Service class UserInfoService { - @Autowired - OpsmxOesService opsmxOesService - Gson gson = new Gson() Object getAllInfoOfUser(User user, Object response) throws Exception { UserInfoDetailsModel userInfoDetails = new UserInfoDetailsModel() try { - log.info("CloudProviderAccounts: {}", response) + log.info("CloudProviderAccounts response from oes service: {}", response) def inputStr = gson.toJson(response) def extractedCloudAccounts = JsonParser.parseString(inputStr).getAsJsonArray() - /*def cloudAccounts = extractedCloudAccounts.collect { - def accountType = it.getAsJsonPrimitive("accountType").getAsString() - def name = it.getAsJsonPrimitive("name").getAsString() - "cloudProvider: " + accountType + " , " + "accountName: " + name - } -*/ def cloudAccounts = extractedCloudAccounts.collect { accountJson -> def accountType = accountJson.getAsJsonPrimitive("accountType").getAsString() def name = accountJson.getAsJsonPrimitive("name").getAsString() - def cloudAccount = [cloudProvider: accountType, accountName: name] cloudAccount } - - log.info("CLoudAccounts: {}", cloudAccounts) + log.info("Extracted cloudAccounts for user: {}", cloudAccounts) userInfoDetails.cloudAccounts = cloudAccounts userInfoDetails.userName = user.username @@ -68,7 +55,6 @@ class UserInfoService { } catch (Exception e) { e.printStackTrace() } - return userInfoDetails } }