Skip to content

Commit a0c27a5

Browse files
authored
EPMRPP-114305 || update GitHub integration: upgrade dependencies and refactor user synchronization logic (#5)
1 parent 04642c8 commit a0c27a5

5 files changed

Lines changed: 40 additions & 49 deletions

File tree

build.gradle

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ plugins {
55
id 'com.gradleup.shadow' version '9.3.1'
66
id "com.github.spotbugs" version "6.4.8"
77
id 'maven-publish'
8-
id("io.freefair.lombok") version "9.2.0"
8+
id("io.freefair.lombok") version "9.5.0"
99
}
1010

1111
apply from: 'project-properties.gradle'
@@ -35,8 +35,8 @@ dependencies {
3535
exclude group: 'org.springframework.modulith', module: 'spring-modulith-apt'
3636
}
3737
} else {
38-
implementation 'com.github.reportportal:service-api:2550296'
39-
annotationProcessor('com.github.reportportal:service-api:2550296') {
38+
implementation 'com.github.reportportal:service-api:336be2c'
39+
annotationProcessor('com.github.reportportal:service-api:336be2c') {
4040
exclude group: 'org.springframework.modulith', module: 'spring-modulith-apt'
4141
}
4242
}

src/main/java/com/epam/reportportal/extension/github/GitHubExtension.java

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,14 @@
3030
import com.epam.reportportal.base.infrastructure.persistence.dao.IntegrationTypeRepository;
3131
import com.epam.reportportal.base.infrastructure.persistence.dao.ProjectRepository;
3232
import com.epam.reportportal.base.infrastructure.persistence.dao.UserRepository;
33+
import com.epam.reportportal.base.infrastructure.persistence.dao.organization.OrganizationRepositoryCustom;
3334
import com.epam.reportportal.base.infrastructure.persistence.entity.enums.IntegrationAuthFlowEnum;
3435
import com.epam.reportportal.base.infrastructure.persistence.util.PersonalProjectService;
3536
import com.epam.reportportal.extension.AuthExtension;
3637
import com.epam.reportportal.extension.CommonPluginCommand;
3738
import com.epam.reportportal.extension.IntegrationGroupEnum;
3839
import com.epam.reportportal.extension.PluginCommand;
40+
import com.epam.reportportal.extension.command.ExtensionCommand;
3941
import com.epam.reportportal.extension.github.command.SynchronizeGithubUserCommand;
4042
import com.epam.reportportal.extension.github.event.listener.PluginLoadedEventListener;
4143
import com.epam.reportportal.extension.github.oauth.GitHubOAuthProvider;
@@ -119,6 +121,9 @@ public boolean supports(Class<?> authentication) {
119121
@Autowired
120122
private IntegrationDuplicateValidator integrationDuplicateValidator;
121123

124+
@Autowired
125+
private OrganizationRepositoryCustom organizationRepository;
126+
122127
@Autowired
123128
private BasicTextEncryptor encryptor;
124129

@@ -127,7 +132,7 @@ public boolean supports(Class<?> authentication) {
127132

128133
private GitHubUserReplicator replicator;
129134
private GitHubOAuthProvider oauthProvider;
130-
private Map<String, CommonPluginCommand<?>> commonCommands;
135+
private Map<String, ExtensionCommand<?>> commonCommands;
131136

132137
private Supplier<GitHubIntegrationStrategy> gitHubIntegrationStrategySupplier;
133138
private Supplier<PluginLoadedEventListener> pluginLoadedListenerSupplier;
@@ -146,11 +151,10 @@ public void init() throws IOException {
146151
integrationType -> integrationType, dataSource));
147152

148153
replicator = new GitHubUserReplicator(
149-
userRepository, projectRepository, personalProjectService,
150-
userBinaryDataService, contentTypeResolver, userEventPublisher
154+
userRepository, userBinaryDataService, contentTypeResolver, userEventPublisher
151155
);
152156
oauthProvider = new GitHubOAuthProvider(replicator);
153-
SynchronizeGithubUserCommand syncCommand = new SynchronizeGithubUserCommand(replicator);
157+
SynchronizeGithubUserCommand syncCommand = new SynchronizeGithubUserCommand(replicator, projectRepository, organizationRepository);
154158
commonCommands = Map.of(syncCommand.getName(), syncCommand);
155159

156160
initListeners();
@@ -211,7 +215,12 @@ public Optional<Map<String, Object>> getAuthProviderInfo() {
211215

212216
@Override
213217
public CommonPluginCommand<?> getCommonCommand(String commandName) {
214-
return commonCommands.get(commandName);
218+
return null;
219+
}
220+
221+
@Override
222+
public Map<String, ExtensionCommand<?>> getCommonExtensionCommands() {
223+
return commonCommands;
215224
}
216225

217226
@Override

src/main/java/com/epam/reportportal/extension/github/GitHubUserReplicator.java

Lines changed: 13 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -25,23 +25,21 @@
2525
import com.epam.reportportal.base.infrastructure.commons.ContentTypeResolver;
2626
import com.epam.reportportal.base.infrastructure.persistence.binary.UserBinaryDataService;
2727
import com.epam.reportportal.base.infrastructure.persistence.commons.ReportPortalUser;
28-
import com.epam.reportportal.base.infrastructure.persistence.dao.ProjectRepository;
2928
import com.epam.reportportal.base.infrastructure.persistence.dao.UserRepository;
3029
import com.epam.reportportal.base.infrastructure.persistence.entity.attachment.BinaryData;
3130
import com.epam.reportportal.base.infrastructure.persistence.entity.user.User;
3231
import com.epam.reportportal.base.infrastructure.persistence.entity.user.UserRole;
3332
import com.epam.reportportal.base.infrastructure.persistence.entity.user.UserType;
34-
import com.epam.reportportal.base.infrastructure.persistence.util.PersonalProjectService;
3533
import com.epam.reportportal.base.infrastructure.rules.exception.ErrorType;
3634
import com.epam.reportportal.base.infrastructure.rules.exception.ReportPortalException;
3735
import com.epam.reportportal.extension.github.client.GitHubClient;
3836
import com.epam.reportportal.extension.github.model.EmailResource;
3937
import com.epam.reportportal.extension.github.model.UserResource;
40-
import java.io.IOException;
4138
import java.io.InputStream;
4239
import java.util.Objects;
4340
import java.util.Optional;
4441
import java.util.UUID;
42+
import lombok.extern.slf4j.Slf4j;
4543
import org.apache.commons.lang3.StringUtils;
4644
import org.springframework.core.io.Resource;
4745
import org.springframework.http.ResponseEntity;
@@ -50,15 +48,14 @@
5048
/**
5149
* Replicates GitHub account info with internal ReportPortal's database.
5250
*/
51+
@Slf4j
5352
public class GitHubUserReplicator extends AbstractUserReplicator {
5453

5554
private final UserEventPublisher userEventPublisher;
5655

57-
public GitHubUserReplicator(UserRepository userRepository, ProjectRepository projectRepository,
58-
PersonalProjectService personalProjectService, UserBinaryDataService userBinaryDataService,
56+
public GitHubUserReplicator(UserRepository userRepository, UserBinaryDataService userBinaryDataService,
5957
ContentTypeResolver contentTypeResolver, UserEventPublisher userEventPublisher) {
60-
super(userRepository, projectRepository, personalProjectService, userBinaryDataService,
61-
contentTypeResolver);
58+
super(userRepository, contentTypeResolver, userBinaryDataService);
6259
this.userEventPublisher = userEventPublisher;
6360
}
6461

@@ -68,7 +65,7 @@ public GitHubUserReplicator(UserRepository userRepository, ProjectRepository pro
6865
* @param accessToken GitHub access token
6966
*/
7067
public void synchronizeUser(String accessToken) {
71-
LOGGER.info("synchronizeUser");
68+
log.info("synchronizeUser");
7269
GitHubClient gitHubClient = GitHubClient.withAccessToken(accessToken);
7370
UserResource userResource = gitHubClient.getUser();
7471

@@ -97,7 +94,7 @@ public void synchronizeUser(String accessToken) {
9794
*/
9895
@Transactional
9996
public ReportPortalUser replicateUser(UserResource userResource, GitHubClient gitHubClient) {
100-
LOGGER.info("replicateUser: login={}", userResource.getLogin());
97+
log.info("replicateUser: login={}", userResource.getLogin());
10198
String email = resolveEmail(userResource, gitHubClient);
10299

103100
User user = userRepository.findByEmail(email).map(u -> {
@@ -119,15 +116,15 @@ public ReportPortalUser replicateUser(UserResource userResource, GitHubClient gi
119116
}
120117

121118
private void updateUser(User user, UserResource userResource, GitHubClient gitHubClient) {
122-
LOGGER.info("updateUser: login={}", user.getLogin());
119+
log.info("updateUser: login={}", user.getLogin());
123120
user.setFullName(
124121
isNullOrEmpty(userResource.getName()) ? user.getLogin() : userResource.getName());
125122
user.setMetadata(defaultMetaData());
126123
uploadAvatar(gitHubClient, user, userResource.getAvatarUrl());
127124
}
128125

129126
private User createUser(UserResource userResource, GitHubClient gitHubClient) {
130-
LOGGER.info("createUser: login={}", userResource.getLogin());
127+
log.info("createUser: login={}", userResource.getLogin());
131128
String email = resolveEmail(userResource, gitHubClient);
132129
User user = new User();
133130
user.setLogin(email);
@@ -142,7 +139,7 @@ private User createUser(UserResource userResource, GitHubClient gitHubClient) {
142139
}
143140

144141
private void uploadAvatar(GitHubClient gitHubClient, User user, String avatarUrl) {
145-
LOGGER.info("uploadAvatar: login={}", user.getLogin());
142+
log.info("uploadAvatar: login={}", user.getLogin());
146143
if (avatarUrl == null) {
147144
return;
148145
}
@@ -157,12 +154,12 @@ private void uploadAvatar(GitHubClient gitHubClient, User user, String avatarUrl
157154
uploadPhoto(user, photo);
158155
}
159156
} catch (Exception e) {
160-
LOGGER.warn("Unable to load avatar for user '{}', skipping: {}", user.getLogin(), e.getMessage(), e);
157+
log.warn("Unable to load avatar for user '{}', skipping: {}", user.getLogin(), e.getMessage(), e);
161158
}
162159
}
163160

164161
private Optional<String> retrievePrimaryEmail(GitHubClient gitHubClient) {
165-
LOGGER.info("retrievePrimaryEmail");
162+
log.info("retrievePrimaryEmail");
166163
return gitHubClient.getUserEmails()
167164
.stream()
168165
.filter(EmailResource::isVerified)
@@ -172,14 +169,13 @@ private Optional<String> retrievePrimaryEmail(GitHubClient gitHubClient) {
172169
}
173170

174171
private String resolveEmail(UserResource user, GitHubClient client) {
175-
LOGGER.info("resolveEmail: login={}", user.getLogin());
172+
log.info("resolveEmail: login={}", user.getLogin());
176173
return Optional.ofNullable(user.getEmail())
177174
.filter(StringUtils::isNotBlank)
178175
.map(NORMALIZE_STRING)
179176
.orElseGet(() -> retrievePrimaryEmail(client)
180177
.map(NORMALIZE_STRING)
181178
.filter(StringUtils::isNotBlank)
182-
.orElseThrow(
183-
() -> new UserSynchronizationException("User 'email' has not been provided")));
179+
.orElseThrow(() -> new UserSynchronizationException("User 'email' has not been provided")));
184180
}
185181
}

src/main/java/com/epam/reportportal/extension/github/command/SynchronizeGithubUserCommand.java

Lines changed: 9 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -17,49 +17,37 @@
1717
package com.epam.reportportal.extension.github.command;
1818

1919
import com.epam.reportportal.api.model.PluginCommandRQ;
20+
import com.epam.reportportal.base.infrastructure.persistence.dao.ProjectRepository;
21+
import com.epam.reportportal.base.infrastructure.persistence.dao.organization.OrganizationRepositoryCustom;
22+
import com.epam.reportportal.base.infrastructure.persistence.entity.user.UserRole;
2023
import com.epam.reportportal.base.infrastructure.rules.commons.validation.BusinessRule;
2124
import com.epam.reportportal.base.infrastructure.rules.exception.ErrorType;
2225
import com.epam.reportportal.base.reporting.OperationCompletionRS;
26+
import com.epam.reportportal.extension.command.AbstractExtensionCommand;
2327
import com.epam.reportportal.extension.github.GitHubUserReplicator;
24-
import com.epam.reportportal.extension.role.AuthenticatedUserContextCommand;
2528
import java.util.Objects;
2629
import lombok.extern.slf4j.Slf4j;
2730

28-
/**
29-
* Command to synchronize GitHub user information.
30-
*
31-
* @author <a href="mailto:andrei_varabyeu@epam.com">Andrei Varabyeu</a>
32-
*/
3331
@Slf4j
34-
public class SynchronizeGithubUserCommand extends AuthenticatedUserContextCommand {
32+
public class SynchronizeGithubUserCommand extends AbstractExtensionCommand<OperationCompletionRS> {
3533

3634
private static final String COMMAND_NAME = "synchronize";
3735
private static final String ACCESS_TOKEN_PARAM = "access_token";
3836

3937
private final GitHubUserReplicator replicator;
4038

41-
/**
42-
* Instantiates a new Synchronize GitHub user command.
43-
*
44-
* @param replicator the replicator
45-
*/
46-
public SynchronizeGithubUserCommand(GitHubUserReplicator replicator) {
39+
public SynchronizeGithubUserCommand(GitHubUserReplicator replicator,
40+
ProjectRepository projectRepository, OrganizationRepositoryCustom organizationRepository) {
41+
super(projectRepository, organizationRepository);
4742
this.replicator = replicator;
43+
this.minUserRole = UserRole.USER;
4844
}
4945

5046
@Override
5147
public String getName() {
5248
return COMMAND_NAME;
5349
}
5450

55-
/**
56-
* {@inheritDoc}
57-
* <p>
58-
* Synchronizes GitHub user information using the provided access token.
59-
*
60-
* @param pluginCommandRq the plugin command rq
61-
* @return the operation completion rs
62-
*/
6351
@Override
6452
protected OperationCompletionRS invokeCommand(PluginCommandRQ pluginCommandRq) {
6553
String accessToken = (String) pluginCommandRq.getArguments().get(ACCESS_TOKEN_PARAM);

src/main/java/com/epam/reportportal/extension/github/oauth/GitHubOAuth2UserService.java

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@
2525
import com.epam.reportportal.extension.github.client.GitHubClient;
2626
import com.epam.reportportal.extension.github.model.OrganizationResource;
2727
import com.epam.reportportal.extension.github.model.UserResource;
28-
import com.google.common.base.Splitter;
2928
import java.util.Collections;
3029
import java.util.List;
3130
import java.util.Optional;
@@ -74,8 +73,7 @@ public OAuth2User loadUser(OAuth2UserRequest userRequest) throws OAuth2Authentic
7473

7574
private List<String> parseAllowedOrganizations(OAuthRegistrationResource registration) {
7675
return Optional.ofNullable(registration.getRestrictions())
77-
.map(restrictions -> restrictions.get("organizations"))
78-
.map(orgs -> Splitter.on(',').omitEmptyStrings().splitToList(orgs))
76+
.map(restrictions -> (List<String>) (Object) restrictions.get("organizations"))
7977
.orElse(Collections.emptyList());
8078
}
8179

0 commit comments

Comments
 (0)