Skip to content

Commit

Permalink
✨ : add strategies to manage oauth2 clients and move them in specific…
Browse files Browse the repository at this point in the history
… package
  • Loading branch information
cdubuisson committed Oct 16, 2019
1 parent cf25f37 commit 0cbcd07
Show file tree
Hide file tree
Showing 15 changed files with 344 additions and 53 deletions.
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
package io.codeka.gaia.modules.repository;

import io.codeka.gaia.modules.bo.TerraformModule;
import io.codeka.gaia.modules.repository.strategy.GitHubStrategy;
import io.codeka.gaia.modules.repository.strategy.GitLabStrategy;
import io.codeka.gaia.modules.repository.strategy.GitPlatformStrategy;
import io.codeka.gaia.registries.RegistryRawContent;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

Expand All @@ -13,11 +11,11 @@
@Repository
public class TerraformModuleGitRepository {

List<GitPlatformStrategy> gitPlatformStrategies;
private List<RegistryRawContent> registryRawContents;

@Autowired
public TerraformModuleGitRepository() {
gitPlatformStrategies = List.of(new GitHubStrategy(), new GitLabStrategy());
public TerraformModuleGitRepository(List<RegistryRawContent> registryRawContents) {
this.registryRawContents = registryRawContents;
}

/**
Expand All @@ -27,7 +25,7 @@ public TerraformModuleGitRepository() {
* @return the url of the README file
*/
public Optional<String> getReadme(TerraformModule module) {
Optional<GitPlatformStrategy> strategy = gitPlatformStrategies.stream()
var strategy = registryRawContents.stream()
.filter(s -> s.matches(module.getGitRepositoryUrl()))
.findFirst();

Expand All @@ -37,5 +35,4 @@ public Optional<String> getReadme(TerraformModule module) {
var url = strategy.get().getRawUrl(module.getGitRepositoryUrl(), module.getGitBranch(), module.getDirectory());
return Optional.of(url + "/README.md");
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package io.codeka.gaia.registries;

import io.codeka.gaia.teams.OAuth2User;
import org.apache.commons.lang.StringUtils;
import org.springframework.security.oauth2.client.OAuth2AuthorizedClient;
import org.springframework.security.oauth2.core.user.DefaultOAuth2User;

public interface RegistryOAuth2Provider {
/**
* Return the name of the provider for the current strategy
*/
String getProvider();

/**
* Determines if the strategy is matching the provider
*/
default boolean isAssignableFor(String provider) {
return StringUtils.equals(getProvider(), provider);
}

/**
* Returns the data from the authorized client
*/
default OAuth2User getOAuth2User(DefaultOAuth2User user, OAuth2AuthorizedClient client) {
return new OAuth2User(
client.getClientRegistration().getRegistrationId(),
client.getAccessToken().getTokenValue(),
user.getAttributes());
}

/**
* Returns the http(s) url filled with oauth2 token
*/
default String getOAuth2Url(String url, String token) {
return url.replaceAll("^(http[s]?://)(.*)$", "$1oauth2:" + token + "@$2");
}
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
package io.codeka.gaia.modules.repository.strategy;
package io.codeka.gaia.registries;

import org.apache.commons.lang.StringUtils;

import java.text.MessageFormat;
import java.util.regex.Pattern;

public abstract class GitPlatformStrategy {
public abstract class RegistryRawContent {

protected static final String DEFAULT_BRANCH = "master";
private static final String DEFAULT_BRANCH = "master";

/**
* Returns the pattern to match the repository url.
Expand Down Expand Up @@ -39,5 +39,4 @@ public String getRawUrl(String url, String branch, String directory) {
}
return StringUtils.EMPTY;
}

}
28 changes: 28 additions & 0 deletions src/main/java/io/codeka/gaia/registries/config/RegistryConfig.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package io.codeka.gaia.registries.config;

import io.codeka.gaia.registries.RegistryOAuth2Provider;
import io.codeka.gaia.registries.RegistryRawContent;
import io.codeka.gaia.registries.github.GitHubOAuth2Provider;
import io.codeka.gaia.registries.github.GitHubRawContent;
import io.codeka.gaia.registries.gitlab.GitLabOAuth2Provider;
import io.codeka.gaia.registries.gitlab.GitLabRawContent;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.List;

/**
* Config for registry management
*/
@Configuration
public class RegistryConfig {
@Bean
List<RegistryRawContent> registryRawContents() {
return List.of(new GitHubRawContent(), new GitLabRawContent());
}

@Bean
List<RegistryOAuth2Provider> registryOAuth2Providers() {
return List.of(new GitHubOAuth2Provider(), new GitLabOAuth2Provider());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package io.codeka.gaia.registries.github;

import io.codeka.gaia.registries.RegistryOAuth2Provider;

public class GitHubOAuth2Provider implements RegistryOAuth2Provider {
@Override
public String getProvider() {
return "github";
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
package io.codeka.gaia.modules.repository.strategy;
package io.codeka.gaia.registries.github;

import java.util.regex.Pattern;
import io.codeka.gaia.registries.RegistryRawContent;

public class GitHubStrategy extends GitPlatformStrategy {
import java.util.regex.Pattern;

public class GitHubRawContent extends RegistryRawContent {
@Override
protected final Pattern getPattern() {
return Pattern.compile("^http[s]?://[www.]?github.com(.*).git$");
Expand All @@ -13,5 +14,4 @@ protected final Pattern getPattern() {
protected String getTemplateRawUrl() {
return "https://raw.githubusercontent.com{0}/{1}";
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package io.codeka.gaia.registries.gitlab;

import io.codeka.gaia.registries.RegistryOAuth2Provider;

public class GitLabOAuth2Provider implements RegistryOAuth2Provider {
@Override
public String getProvider() {
return "gitlab";
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
package io.codeka.gaia.modules.repository.strategy;
package io.codeka.gaia.registries.gitlab;

import java.util.regex.Pattern;
import io.codeka.gaia.registries.RegistryRawContent;

public class GitLabStrategy extends GitPlatformStrategy {
import java.util.regex.Pattern;

public class GitLabRawContent extends RegistryRawContent {
@Override
protected final Pattern getPattern() {
return Pattern.compile("^(http[s]?://[www.]?gitlab.*).git$");
Expand All @@ -13,5 +14,4 @@ protected final Pattern getPattern() {
protected String getTemplateRawUrl() {
return "{0}/raw/{1}";
}

}
12 changes: 11 additions & 1 deletion src/main/java/io/codeka/gaia/teams/bo.kt
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,14 @@ data class User(

val isAdmin: Boolean
get() = "admin" == this.username
}

var oAuth2User: OAuth2User? = null
}

/**
* Gather data of user identified by OAuth2
*/
data class OAuth2User(
val provider: String?,
val token: String?,
val attributes: Map<String, Any>?)
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package io.codeka.gaia.modules.repository;

import io.codeka.gaia.modules.bo.TerraformModule;
import io.codeka.gaia.modules.repository.strategy.GitPlatformStrategy;
import io.codeka.gaia.registries.RegistryRawContent;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
Expand All @@ -19,15 +19,14 @@
@ExtendWith(MockitoExtension.class)
class TerraformModuleGitRepositoryTest {

private TerraformModuleGitRepository repository;

@Mock
private GitPlatformStrategy strategy;
RegistryRawContent registryRawContent;

private TerraformModuleGitRepository repository;

@BeforeEach
void setup() {
repository = new TerraformModuleGitRepository();
repository.gitPlatformStrategies = List.of(strategy);
repository = new TerraformModuleGitRepository(List.of(registryRawContent));
}

@Test
Expand All @@ -39,14 +38,14 @@ void getReadme_shouldReturnReadme() {
module.setDirectory("directory");

// when
when(strategy.matches(anyString())).thenReturn(true);
when(strategy.getRawUrl(anyString(), anyString(), anyString())).thenReturn("raw_url");
when(registryRawContent.matches(anyString())).thenReturn(true);
when(registryRawContent.getRawUrl(anyString(), anyString(), anyString())).thenReturn("raw_url");
var result = repository.getReadme(module);

// then
assertThat(result).isPresent().get().isEqualTo("raw_url/README.md");
verify(strategy).matches("url");
verify(strategy).getRawUrl("url", "branch", "directory");
verify(registryRawContent).matches("url");
verify(registryRawContent).getRawUrl("url", "branch", "directory");
}

@Test
Expand All @@ -55,11 +54,10 @@ void getReadme_shouldReturnNothingIfNoStrategyFound() {
var module = new TerraformModule();

// when
when(strategy.matches(any())).thenReturn(false);
when(registryRawContent.matches(any())).thenReturn(false);
var result = repository.getReadme(module);

// then
assertThat(result).isEmpty();
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package io.codeka.gaia.registries.config;

import io.codeka.gaia.registries.RegistryOAuth2Provider;
import io.codeka.gaia.registries.RegistryRawContent;
import io.codeka.gaia.registries.github.GitHubOAuth2Provider;
import io.codeka.gaia.registries.github.GitHubRawContent;
import io.codeka.gaia.registries.gitlab.GitLabOAuth2Provider;
import io.codeka.gaia.registries.gitlab.GitLabRawContent;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.List;

import static org.assertj.core.api.Assertions.assertThat;

@SpringBootTest(classes = RegistryConfig.class)
class RegistryConfigIT {
@Test
void registryRawContents_shouldBeInstantiated(@Autowired(required = false) List<RegistryRawContent> registryRawContents) {
assertThat(registryRawContents).isNotNull()
.hasSize(2)
.extracting("class")
.contains(GitHubRawContent.class, GitLabRawContent.class);
}

@Test
void registryOAuth2Providers_shouldBeInstantiated(@Autowired(required = false) List<RegistryOAuth2Provider> registryOAuth2Providers) {
assertThat(registryOAuth2Providers).isNotNull()
.hasSize(2)
.extracting("class")
.contains(GitHubOAuth2Provider.class, GitLabOAuth2Provider.class);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
package io.codeka.gaia.registries.github;

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.security.oauth2.client.OAuth2AuthorizedClient;
import org.springframework.security.oauth2.client.registration.ClientRegistration;
import org.springframework.security.oauth2.core.AuthorizationGrantType;
import org.springframework.security.oauth2.core.OAuth2AccessToken;
import org.springframework.security.oauth2.core.user.DefaultOAuth2User;

import java.util.HashMap;

import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

class GitHubOAuth2ProviderTest {

private GitHubOAuth2Provider gitHubOAuth2Provider;

@BeforeEach
void setup() {
gitHubOAuth2Provider = new GitHubOAuth2Provider();
}

@Test
void getProvider_shouldReturnProvider() {
assertNotNull(gitHubOAuth2Provider.getProvider());
}

@Test
void isAssignableFor_shouldReturnTrue_forValidProvider() {
assertTrue(gitHubOAuth2Provider.isAssignableFor("github"));
}

@Test
void isAssignableFor_shouldReturnFalse_forInvalidProvider() {
assertFalse(gitHubOAuth2Provider.isAssignableFor("gitlab"));
}

@Test
void getOAuth2User_shouldReturnANewOAuthUser() {
// given
var attributes = new HashMap<String, Object>();
var user = mock(DefaultOAuth2User.class);
var client = mock(OAuth2AuthorizedClient.class);
var registration = ClientRegistration
.withRegistrationId("test_registration_id")
.authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
.clientId("test_client_id")
.redirectUriTemplate("test_uri_template")
.authorizationUri("test_authorization_uri")
.tokenUri("test_token_uri")
.build();
var accessToken = mock(OAuth2AccessToken.class);

// when
when(user.getAttributes()).thenReturn(attributes);
when(client.getClientRegistration()).thenReturn(registration);
when(client.getAccessToken()).thenReturn(accessToken);
when(accessToken.getTokenValue()).thenReturn("test_token");
var result = gitHubOAuth2Provider.getOAuth2User(user, client);

// then
assertThat(result).isNotNull()
.hasFieldOrPropertyWithValue("provider", "test_registration_id")
.hasFieldOrPropertyWithValue("token", "test_token")
.hasFieldOrPropertyWithValue("attributes", attributes);
}

@Test
void getOAuth2Url_shouldReturnUrl_withToken() {
// given
var url = "https://github.com/CodeKaio/gaia.git";
var token = "test_token";

// when
var result = gitHubOAuth2Provider.getOAuth2Url(url, token);

// then
assertThat(result).isNotNull().isEqualTo("https://oauth2:[email protected]/CodeKaio/gaia.git");
}
}
Loading

0 comments on commit 0cbcd07

Please sign in to comment.