-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #9 from leanix/feature/CID-1829/validate-configura…
…tion CID-1829: validate configuration
- Loading branch information
Showing
13 changed files
with
275 additions
and
6 deletions.
There are no files selected for viewing
20 changes: 20 additions & 0 deletions
20
src/main/kotlin/net/leanix/vsm/gitlab/broker/connector/adapter/feign/GitlabClient.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
package net.leanix.vsm.gitlab.broker.connector.adapter.feign | ||
|
||
import net.leanix.vsm.gitlab.broker.connector.adapter.feign.data.GitlabGroup | ||
import net.leanix.vsm.gitlab.broker.connector.adapter.feign.data.GitlabUser | ||
import net.leanix.vsm.gitlab.broker.shared.auth.adapter.feign.GitlabFeignClientConfiguration | ||
import org.springframework.cloud.openfeign.FeignClient | ||
import org.springframework.web.bind.annotation.GetMapping | ||
|
||
@FeignClient( | ||
name = "gitlab", | ||
url = "\${leanix.vsm.connector.gitlab-url}/api/v4", | ||
configuration = [GitlabFeignClientConfiguration::class] | ||
) | ||
interface GitlabClient { | ||
@GetMapping("/user") | ||
fun getCurrentUser(): GitlabUser | ||
|
||
@GetMapping("/groups") | ||
fun getAllGroups(): List<GitlabGroup> | ||
} |
9 changes: 9 additions & 0 deletions
9
src/main/kotlin/net/leanix/vsm/gitlab/broker/connector/adapter/feign/GitlabClientProvider.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
package net.leanix.vsm.gitlab.broker.connector.adapter.feign | ||
|
||
import net.leanix.vsm.gitlab.broker.connector.adapter.feign.data.GitlabGroup | ||
import net.leanix.vsm.gitlab.broker.connector.adapter.feign.data.GitlabUser | ||
|
||
interface GitlabClientProvider { | ||
fun getCurrentUser(): GitlabUser | ||
fun getGroupByFullPath(fullPath: String): GitlabGroup? | ||
} |
29 changes: 29 additions & 0 deletions
29
.../kotlin/net/leanix/vsm/gitlab/broker/connector/adapter/feign/GitlabFeignClientProvider.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
package net.leanix.vsm.gitlab.broker.connector.adapter.feign | ||
|
||
import net.leanix.vsm.gitlab.broker.connector.adapter.feign.data.GitlabGroup | ||
import net.leanix.vsm.gitlab.broker.connector.adapter.feign.data.GitlabUser | ||
import net.leanix.vsm.gitlab.broker.shared.exception.InvalidToken | ||
import net.leanix.vsm.gitlab.broker.shared.exception.OrgNameValidationFailed | ||
import org.slf4j.LoggerFactory | ||
import org.springframework.stereotype.Component | ||
|
||
@Component | ||
class GitlabFeignClientProvider( | ||
private val gitlabClient: GitlabClient | ||
) : GitlabClientProvider { | ||
|
||
private val logger = LoggerFactory.getLogger(GitlabFeignClientProvider::class.java) | ||
|
||
override fun getCurrentUser(): GitlabUser { | ||
return runCatching { gitlabClient.getCurrentUser() }.onFailure { | ||
logger.error("Invalid token, could not get current user") | ||
throw InvalidToken() | ||
}.getOrThrow() | ||
} | ||
|
||
override fun getGroupByFullPath(fullPath: String): GitlabGroup? { | ||
return runCatching { | ||
gitlabClient.getAllGroups().first { it.fullPath == fullPath } | ||
}.onFailure { throw OrgNameValidationFailed() }.getOrThrow() | ||
} | ||
} |
10 changes: 10 additions & 0 deletions
10
src/main/kotlin/net/leanix/vsm/gitlab/broker/connector/adapter/feign/data/GitlabGroup.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
package net.leanix.vsm.gitlab.broker.connector.adapter.feign.data | ||
|
||
import com.fasterxml.jackson.annotation.JsonProperty | ||
|
||
class GitlabGroup( | ||
@JsonProperty("id") | ||
val id: Int, | ||
@JsonProperty("full_path") | ||
val fullPath: String | ||
) |
10 changes: 10 additions & 0 deletions
10
src/main/kotlin/net/leanix/vsm/gitlab/broker/connector/adapter/feign/data/GitlabUser.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
package net.leanix.vsm.gitlab.broker.connector.adapter.feign.data | ||
|
||
import com.fasterxml.jackson.annotation.JsonProperty | ||
|
||
class GitlabUser( | ||
@JsonProperty("id") | ||
val id: Int, | ||
@JsonProperty("is_admin") | ||
val isAdmin: Boolean? | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
61 changes: 61 additions & 0 deletions
61
src/main/kotlin/net/leanix/vsm/gitlab/broker/connector/application/ValidationService.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
package net.leanix.vsm.gitlab.broker.connector.application | ||
|
||
import feign.FeignException | ||
import net.leanix.vsm.gitlab.broker.connector.adapter.feign.GitlabClientProvider | ||
import net.leanix.vsm.gitlab.broker.connector.domain.GitLabAssignment | ||
import net.leanix.vsm.gitlab.broker.shared.exception.AccessLevelValidationFailed | ||
import net.leanix.vsm.gitlab.broker.shared.exception.InvalidToken | ||
import net.leanix.vsm.gitlab.broker.shared.exception.OrgNameValidationFailed | ||
import org.springframework.stereotype.Component | ||
|
||
@Component | ||
class ValidationService( | ||
private val gitlabClientProvider: GitlabClientProvider | ||
) : BaseConnectorService() { | ||
|
||
fun validateConfiguration(gitLabAssignment: GitLabAssignment) { | ||
val orgName = gitLabAssignment.connectorConfiguration.orgName | ||
runCatching { | ||
validateUserAccess() | ||
validateGroupPath(orgName) | ||
}.onSuccess { | ||
logInfoMessages("vsm.configuration.validation.successful", arrayOf(orgName), gitLabAssignment) | ||
}.onFailure { exception -> | ||
handleExceptions(exception, orgName, gitLabAssignment) | ||
} | ||
} | ||
|
||
private fun validateUserAccess() { | ||
if (gitlabClientProvider.getCurrentUser().isAdmin != true) throw AccessLevelValidationFailed() | ||
} | ||
|
||
private fun validateGroupPath(fullPath: String) { | ||
if (gitlabClientProvider.getGroupByFullPath(fullPath) == null) throw OrgNameValidationFailed() | ||
} | ||
|
||
private fun handleExceptions( | ||
exception: Throwable, | ||
orgName: String, | ||
gitLabAssignment: GitLabAssignment | ||
) { | ||
when (exception) { | ||
is InvalidToken -> { | ||
logFailedMessages("vsm.configuration.invalid_token", arrayOf(orgName), gitLabAssignment) | ||
} | ||
|
||
is AccessLevelValidationFailed -> { | ||
logFailedMessages("vsm.configuration.access_level", arrayOf(orgName), gitLabAssignment) | ||
} | ||
|
||
is OrgNameValidationFailed -> { | ||
logFailedMessages("vsm.configuration.invalid_org_name", arrayOf(orgName), gitLabAssignment) | ||
} | ||
|
||
is FeignException -> { | ||
logFailedMessages("vsm.configuration.validation.failed", arrayOf(orgName), gitLabAssignment) | ||
} | ||
} | ||
logFailedStatus(exception.message, gitLabAssignment) | ||
throw exception | ||
} | ||
} |
4 changes: 2 additions & 2 deletions
4
.../GitlabWebhookFeignClientConfiguration.kt → ...r/feign/GitlabFeignClientConfiguration.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,8 @@ | ||
vsm.repos.not_found=Zero repositories found in {0} GitHub organisation. Hint: In case organisation is valid, check if the inclusion list has at least one valid repository name. | ||
vsm.repos.total=Fetched Org Repositories Ids. Result : {0} repos | ||
vsm.repos.imported=Repository Imported | ||
vsm.repos.imported=Repository Imported | ||
vsm.configuration.validation.successful=Validation successful for configuration with group/subgroup path {0} | ||
vsm.configuration.validation.failed=Validation failed for configuration with group/subgroup path {0} | ||
vsm.configuration.invalid_token=Invalid token in configuration with group/subgroup path {0} | ||
vsm.configuration.access_level=Access level insufficient for configuration with group/subgroup path {0} | ||
vsm.configuration.invalid_org_name=Invalid group/subgroup path in configuration with group/subgroup path {0} |
85 changes: 85 additions & 0 deletions
85
src/test/kotlin/net/leanix/vsm/gitlab/broker/connector/application/ValidationServiceTest.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
package net.leanix.vsm.gitlab.broker.connector.application | ||
|
||
import io.mockk.every | ||
import io.mockk.mockk | ||
import io.mockk.verify | ||
import net.leanix.vsm.gitlab.broker.connector.adapter.feign.GitlabClient | ||
import net.leanix.vsm.gitlab.broker.connector.adapter.feign.GitlabFeignClientProvider | ||
import net.leanix.vsm.gitlab.broker.connector.shared.DataBuilder | ||
import net.leanix.vsm.gitlab.broker.logs.application.LoggingService | ||
import net.leanix.vsm.gitlab.broker.shared.exception.AccessLevelValidationFailed | ||
import net.leanix.vsm.gitlab.broker.shared.exception.InvalidToken | ||
import net.leanix.vsm.gitlab.broker.shared.exception.OrgNameValidationFailed | ||
import org.junit.jupiter.api.BeforeEach | ||
import org.junit.jupiter.api.Test | ||
import org.junit.jupiter.api.assertThrows | ||
import org.springframework.context.MessageSource | ||
|
||
class ValidationServiceTest { | ||
|
||
private val messageSource = mockk<MessageSource>() | ||
private val loggingService = mockk<LoggingService>() | ||
private val gitlabClient = mockk<GitlabClient>() | ||
private val gitlabFeignClientProvider = GitlabFeignClientProvider(gitlabClient) | ||
private val validationService = ValidationService(gitlabFeignClientProvider) | ||
|
||
@BeforeEach | ||
fun setUp() { | ||
validationService.messageSource = messageSource | ||
validationService.loggingService = loggingService | ||
|
||
every { messageSource.getMessage(allAny(), allAny(), allAny()) } returns "mock-message" | ||
every { loggingService.sendAdminLog(any()) } returns Unit | ||
every { loggingService.sendStatusLog(any()) } returns Unit | ||
} | ||
|
||
@Test | ||
fun `it should validate the configuration`() { | ||
every { gitlabClient.getCurrentUser() } returns DataBuilder.getGitlabCurrentUser(true) | ||
every { gitlabClient.getAllGroups() } returns DataBuilder.getAllGroups() | ||
|
||
validationService.validateConfiguration(DataBuilder.getGitlabAssignment()) | ||
|
||
verify(exactly = 1) { gitlabClient.getCurrentUser() } | ||
verify(exactly = 1) { gitlabClient.getAllGroups() } | ||
} | ||
|
||
@Test | ||
fun `it should not validate the configuration if token is invalid`() { | ||
every { gitlabClient.getCurrentUser() } throws Exception() | ||
every { gitlabClient.getAllGroups() } returns DataBuilder.getAllGroups() | ||
|
||
assertThrows<InvalidToken> { | ||
validationService.validateConfiguration(DataBuilder.getGitlabAssignment()) | ||
} | ||
|
||
verify(exactly = 1) { gitlabClient.getCurrentUser() } | ||
verify(exactly = 0) { gitlabClient.getAllGroups() } | ||
} | ||
|
||
@Test | ||
fun `it should not validate the configuration if user is not admin`() { | ||
every { gitlabClient.getCurrentUser() } returns DataBuilder.getGitlabCurrentUser(false) | ||
every { gitlabClient.getAllGroups() } returns DataBuilder.getAllGroups() | ||
|
||
assertThrows<AccessLevelValidationFailed> { | ||
validationService.validateConfiguration(DataBuilder.getGitlabAssignment()) | ||
} | ||
|
||
verify(exactly = 1) { gitlabClient.getCurrentUser() } | ||
verify(exactly = 0) { gitlabClient.getAllGroups() } | ||
} | ||
|
||
@Test | ||
fun `it should not validate the configuration if group name is invalid`() { | ||
every { gitlabClient.getCurrentUser() } returns DataBuilder.getGitlabCurrentUser(true) | ||
every { gitlabClient.getAllGroups() } throws Exception() | ||
|
||
assertThrows<OrgNameValidationFailed> { | ||
validationService.validateConfiguration(DataBuilder.getGitlabAssignment()) | ||
} | ||
|
||
verify(exactly = 1) { gitlabClient.getCurrentUser() } | ||
verify(exactly = 1) { gitlabClient.getAllGroups() } | ||
} | ||
} |
33 changes: 33 additions & 0 deletions
33
src/test/kotlin/net/leanix/vsm/gitlab/broker/connector/shared/DataBuilder.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
package net.leanix.vsm.gitlab.broker.connector.shared | ||
|
||
import net.leanix.vsm.gitlab.broker.connector.adapter.feign.data.GitlabGroup | ||
import net.leanix.vsm.gitlab.broker.connector.adapter.feign.data.GitlabUser | ||
import net.leanix.vsm.gitlab.broker.connector.domain.GitLabAssignment | ||
import net.leanix.vsm.gitlab.broker.connector.domain.GitLabConfiguration | ||
import java.util.* | ||
|
||
object DataBuilder { | ||
|
||
fun getGitlabAssignment() = GitLabAssignment( | ||
runId = UUID.randomUUID(), | ||
workspaceId = UUID.randomUUID(), | ||
configurationId = UUID.randomUUID(), | ||
connectorConfiguration = GitLabConfiguration("group-1") | ||
) | ||
|
||
fun getGitlabCurrentUser(isAdmin: Boolean) = GitlabUser( | ||
id = 1, | ||
isAdmin = isAdmin | ||
) | ||
|
||
fun getAllGroups() = listOf( | ||
GitlabGroup( | ||
id = 1, | ||
fullPath = "group-1", | ||
), | ||
GitlabGroup( | ||
id = 2, | ||
fullPath = "group-2", | ||
) | ||
) | ||
} |