diff --git a/pom.xml b/pom.xml index f46bbb52ac9916060500d4fc6b670a084eb07a42..c3c1f52e5692ef89f25010dcd2f217b51ca0df33 100644 --- a/pom.xml +++ b/pom.xml @@ -285,7 +285,7 @@ <dependency> <groupId>org.gitlab4j</groupId> <artifactId>gitlab4j-api</artifactId> - <version>5.0.1</version> + <version>5.6.0</version> </dependency> <dependency> <groupId>org.eclipse.jgit</groupId> diff --git a/src/main/java/at/ac/uibk/gitsearch/config/CacheConfiguration.java b/src/main/java/at/ac/uibk/gitsearch/config/CacheConfiguration.java index 433b24ae6a4a54c37a8718003d6010132669ae99..c1cd5357121532429746a760f32d644092304f07 100644 --- a/src/main/java/at/ac/uibk/gitsearch/config/CacheConfiguration.java +++ b/src/main/java/at/ac/uibk/gitsearch/config/CacheConfiguration.java @@ -1,5 +1,6 @@ package at.ac.uibk.gitsearch.config; +import at.ac.uibk.gitsearch.repository.gitlab.GitLabRepository; import at.ac.uibk.gitsearch.repository.search.MetaDataRepository; import at.ac.uibk.gitsearch.service.EditorialPagesService; import java.time.Duration; @@ -50,6 +51,7 @@ public class CacheConfiguration { return cm -> { createCache(cm, at.ac.uibk.gitsearch.repository.jpa.UserRepository.USERS_BY_LOGIN_CACHE); createCache(cm, at.ac.uibk.gitsearch.repository.jpa.UserRepository.USERS_BY_EMAIL_CACHE); + createCache(cm, GitLabRepository.FULLPATH_OF_GROUP_CACHE); createCache(cm, EditorialPagesService.PAGES_CACHE); createCache(cm, EditorialPagesService.HELPMENUTREE_CACHE); diff --git a/src/main/java/at/ac/uibk/gitsearch/repository/gitlab/GitLabRepository.java b/src/main/java/at/ac/uibk/gitsearch/repository/gitlab/GitLabRepository.java index 02088a8a2d18f6e6742f3d09c050b3769c0e2263..1ce65020fc98edef7466d334657193a4920279b9 100644 --- a/src/main/java/at/ac/uibk/gitsearch/repository/gitlab/GitLabRepository.java +++ b/src/main/java/at/ac/uibk/gitsearch/repository/gitlab/GitLabRepository.java @@ -8,16 +8,20 @@ import java.util.stream.Stream; import org.gitlab4j.api.Constants.TokenType; import org.gitlab4j.api.GitLabApi; import org.gitlab4j.api.GitLabApiException; +import org.gitlab4j.api.models.Group; import org.gitlab4j.api.models.Project; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; +import org.springframework.cache.annotation.Cacheable; import org.springframework.stereotype.Repository; @Repository public class GitLabRepository { + public static final String FULLPATH_OF_GROUP_CACHE = "fullPathOfGroupCache"; + @SuppressWarnings("unused") private final Logger log = LoggerFactory.getLogger(GitLabRepository.class); @@ -95,4 +99,18 @@ public class GitLabRepository { public Stream<Project> streamAllProjects() throws GitLabApiException { return getAdminGitLabApi().getProjectApi().getProjectsStream(); } + + /** + * just a helper method, that caches the group namespaces + * + * @param gitLabApi + * @param groupId + * @return + * @throws GitLabApiException + */ + @Cacheable(cacheNames = FULLPATH_OF_GROUP_CACHE) + public String getFullPathOfGroup(final Long groupId) throws GitLabApiException { + final Group group = getAdminGitLabApi().getGroupApi().getGroup(groupId); + return group.getFullPath(); + } } diff --git a/src/main/java/at/ac/uibk/gitsearch/repository/search/ElasticSearchRepository.java b/src/main/java/at/ac/uibk/gitsearch/repository/search/ElasticSearchRepository.java index 2254b2aa208a711130893305bb3c85f5fe9dcbab..45b5645436ac51126030590b71e9ea6b90edcd53 100644 --- a/src/main/java/at/ac/uibk/gitsearch/repository/search/ElasticSearchRepository.java +++ b/src/main/java/at/ac/uibk/gitsearch/repository/search/ElasticSearchRepository.java @@ -24,6 +24,7 @@ import co.elastic.clients.elasticsearch.indices.DeleteIndexResponse; import co.elastic.clients.elasticsearch.indices.update_aliases.AddAction; import java.io.IOException; import java.io.InputStream; +import java.text.ParseException; import java.util.Collections; import java.util.List; import java.util.Optional; @@ -33,6 +34,7 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.codeability.sharing.plugins.api.search.SearchResultDTO; import org.codeability.sharing.plugins.api.search.SearchStatisticsDTO; +import org.codeability.sharing.plugins.api.search.util.ExerciseId; import org.springframework.context.ApplicationContext; import org.springframework.stereotype.Repository; @@ -71,8 +73,21 @@ public class ElasticSearchRepository { * @throws IOException */ public String index(final SearchResultDTO document, String index) throws IOException { - this.elasticsearchAPIClient.index(i -> i.index(index).id(document.getExerciseId()).document(document)); - return document.getExerciseId(); + this.elasticsearchAPIClient.index(i -> { + final String exerciseId = document.getExerciseId(); + return i.index(index).id(exerciseId).document(document); + }); + final String exerciseId2 = document.getExerciseId(); + if (exerciseId2 == null) { + LOGGER.error("Somehow we got an empty exerciseId in {}", document); + } else { + try { + ExerciseId.fromString(exerciseId2); + } catch (ParseException e) { + LOGGER.error("Somehow we got an corrupt exerciseId {}", exerciseId2, e); + } + } + return exerciseId2; } public void waitForIndexingFinished() throws IOException { @@ -147,9 +162,13 @@ public class ElasticSearchRepository { * @throws ElasticsearchException * @throws IOException */ + @SuppressWarnings("null") public SearchResultDTO get(final String docId) throws IOException { final GetResponse<SearchResultDTO> searchResultDTOResponse = this.elasticsearchAPIClient.get(r -> r.index(SearchRepositoryConstants.INDEX_METADATA).id(docId), SearchResultDTO.class); + if (searchResultDTOResponse.source() != null) { + searchResultDTOResponse.source().setExerciseId(docId); + } return searchResultDTOResponse.source(); } diff --git a/src/main/java/at/ac/uibk/gitsearch/security/oauth2/UserDetailsFetcher.java b/src/main/java/at/ac/uibk/gitsearch/security/oauth2/UserDetailsFetcher.java index e03a7e3e61db607d5d2bb34708e390be9d050d3f..9c4f010bed059b1ae32e43675fa1df9ecec1b393 100644 --- a/src/main/java/at/ac/uibk/gitsearch/security/oauth2/UserDetailsFetcher.java +++ b/src/main/java/at/ac/uibk/gitsearch/security/oauth2/UserDetailsFetcher.java @@ -1,6 +1,7 @@ package at.ac.uibk.gitsearch.security.oauth2; import at.ac.uibk.gitsearch.domain.Authority; +import at.ac.uibk.gitsearch.repository.gitlab.GitLabRepository; import at.ac.uibk.gitsearch.service.dto.AdminUserDTO; import java.time.Instant; import java.util.ArrayList; @@ -11,6 +12,7 @@ import java.util.List; import java.util.Optional; import java.util.Set; import java.util.function.Consumer; +import java.util.stream.Stream; import org.apache.commons.lang3.RandomStringUtils; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -20,7 +22,9 @@ import org.gitlab4j.api.GitLabApiException; import org.gitlab4j.api.models.ImpersonationToken; import org.gitlab4j.api.models.ImpersonationToken.Scope; import org.gitlab4j.api.models.Membership; +import org.gitlab4j.api.models.MembershipSourceType; import org.gitlab4j.api.models.User; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.security.oauth2.core.oidc.user.OidcUser; import org.springframework.stereotype.Component; @@ -36,6 +40,9 @@ public class UserDetailsFetcher { @Value("${application.gitlab.url}") private String gitlabURI; + @Autowired + private GitLabRepository gitLabRepository; + /** * just a holder class for the return of update User */ @@ -117,10 +124,7 @@ public class UserDetailsFetcher { } userToken = requestGitLabUserToken(gitUser, gitLabApi); - List<Membership> memberships = gitLabApi.getUserApi().getMemberships(gitUser.getId()); - for (Membership membership : memberships) { - authorities.add(membership.getSourceName()); - } + getUserMemberships(gitLabApi, gitUser).forEach(gitAuthority -> authorities.add(gitAuthority)); modified |= updateAttribute(gitUser.getAvatarUrl(), u.getImageUrl(), u::setImageUrl); modified |= updateAttribute(gitUser.getEmail(), u.getEmail(), u::setEmail); @@ -141,6 +145,36 @@ public class UserDetailsFetcher { return new UserDetailsInfo(userToken, modified); } + /** + * returns the pathes of all groups the user belongs to + * + * @param gitLabApi + * @param gitUser + * @return + */ + public Stream<String> getUserMemberships(GitLabApi gitLabApi, User gitUser) { + List<Membership> memberships; + try { + memberships = gitLabApi.getUserApi().getMemberships(gitUser.getId()); + } catch (GitLabApiException e) { + logger.warn("Cannot read group path for {}", gitUser); + return Stream.empty(); + } + return memberships + .stream() + .filter(membership -> MembershipSourceType.NAMESPACE.equals(membership.getSourceType())) + .map(membership -> membership.getSourceId()) // map to group id + .map(groupId -> { + try { + return gitLabRepository.getFullPathOfGroup(groupId); + } catch (GitLabApiException e) { + logger.warn("Cannot read group path for {}", groupId); + return null; + } + }) + .filter(path -> path != null); + } + private String generatePassword() { return RandomStringUtils.random(8, "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz=%$-."); } diff --git a/src/main/java/at/ac/uibk/gitsearch/service/StatisticsService.java b/src/main/java/at/ac/uibk/gitsearch/service/StatisticsService.java index 98c444e9fb3cb73cf85c118cfbd66ebbbe735ea3..3ca27991a85bc6514b4c6d75a52df17f52d9c61b 100644 --- a/src/main/java/at/ac/uibk/gitsearch/service/StatisticsService.java +++ b/src/main/java/at/ac/uibk/gitsearch/service/StatisticsService.java @@ -4,6 +4,7 @@ import at.ac.uibk.gitsearch.domain.Statistics; import at.ac.uibk.gitsearch.repository.jpa.StatisticsRepository; import at.ac.uibk.gitsearch.repository.search.ElasticSearchRepository; import at.ac.uibk.gitsearch.service.dto.StatisticsDTO; +import at.ac.uibk.gitsearch.service.mapper.StatisticsMapper; import java.io.IOException; import java.util.List; import java.util.Map; @@ -35,6 +36,9 @@ public class StatisticsService { @Autowired private ElasticSearchRepository elasticSearchRepository; + @Autowired + private StatisticsMapper statisticsMapper; + /** * Save a statistics. * @@ -231,7 +235,8 @@ public class StatisticsService { entry = statistics.get(statistics.size() - 1); // last one } updater.update(entry); - statisticsRepository.save(entry); + entry = statisticsRepository.save(entry); + updateSearchResult(statisticsMapper.toDto(entry)); } public void removeBadgeForStatisticsByExerciseID(String exerciseID) { diff --git a/src/main/java/at/ac/uibk/gitsearch/service/gitlab_events/GitlabEventService.java b/src/main/java/at/ac/uibk/gitsearch/service/gitlab_events/GitlabEventService.java index 6285a3ba04b337ccd7f5f3dcca460dabcb282b3e..383111b7d731b7344c1c5f51e577ea073f6706bd 100644 --- a/src/main/java/at/ac/uibk/gitsearch/service/gitlab_events/GitlabEventService.java +++ b/src/main/java/at/ac/uibk/gitsearch/service/gitlab_events/GitlabEventService.java @@ -56,10 +56,12 @@ import org.gitlab4j.api.GitLabApi; import org.gitlab4j.api.GitLabApiException; import org.gitlab4j.api.models.Branch; import org.gitlab4j.api.models.Commit; +import org.gitlab4j.api.models.Group; import org.gitlab4j.api.models.Member; import org.gitlab4j.api.models.Project; import org.gitlab4j.api.models.ProjectSharedGroup; import org.gitlab4j.api.models.RepositoryFile; +import org.gitlab4j.api.models.SharedGroup; import org.gitlab4j.api.models.TreeItem; import org.gitlab4j.api.models.User; import org.gitlab4j.api.systemhooks.GroupSystemHookEvent; @@ -581,24 +583,51 @@ public class GitlabEventService { ProjectPermissions result = new ProjectPermissions(); adminGitLabApi.enableRequestResponseLogging(java.util.logging.Level.INFO); try { - for (Member member : adminGitLabApi.getProjectApi().getMembers(p.getId())) { + for (Member member : adminGitLabApi.getProjectApi().getAllMembers(p.getId())) { if (member.getEmail() == null) { // member does not show email address? User user = adminGitLabApi.getUserApi().getUser(member.getId()); - result.emailAddressesWithAccess.add(user.getEmail()); + result.addEmailWithAccess(user.getEmail()); } else { - result.emailAddressesWithAccess.add(member.getEmail()); + result.addEmailWithAccess(member.getEmail()); } } } catch (GitLabApiException e) { logger.error("Cannot access members for {} ({})", p.getNameWithNamespace(), p.getId(), e); } - final List<ProjectSharedGroup> sharedWithGroups = p.getSharedWithGroups(); + List<String> allGroups = getDirectAndIndirectGroups(p); + allGroups.forEach(group -> result.addGroupWithAccess(group)); + return result; + } + + @SuppressWarnings("deprecation") + protected List<String> getDirectAndIndirectGroups(Project p) { + final List<ProjectSharedGroup> sharedWithGroups = p.getSharedWithGroups(); // returns only direct groups + List<String> allGroups = new ArrayList<>(); for (ProjectSharedGroup group : sharedWithGroups) { - result.groupsWithAccess.add(group.getGroupName()); + allGroups.add(group.getGroupFullPath()); } - return result; + allGroups.addAll(getDirectAndIndirectGroups(p.getNamespace().getId())); + return allGroups; + } + + protected List<String> getDirectAndIndirectGroups(Long groupId) { + List<String> allGroups = new ArrayList<>(); + try { + final Group group = adminGitLabApi.getGroupApi().getGroup(groupId); + if (group != null) { + final List<SharedGroup> sharedGroups = group.getSharedWithGroups(); + sharedGroups.forEach(g -> allGroups.add(g.getGroupFullPath())); + final Long parentId = group.getParentId(); + if (parentId != null) { + allGroups.addAll(getDirectAndIndirectGroups(parentId)); + } + } + } catch (GitLabApiException e) { + logger.warn("Cannot retrieve subgroups of {}", groupId); + } + return allGroups; } public class Indexing { @@ -635,8 +664,8 @@ public class GitlabEventService { gp.setArchived(p.getArchived()); gp.setVisibility(p.getVisibility()); - gp.setUsers(perm.getEmailAddressesWithAccess()); - gp.setGroups(perm.getGroupsWithAccess()); + gp.setUsers(new ArrayList<>(perm.getEmailAddressesWithAccess())); + gp.setGroups(new ArrayList<>(perm.getGroupsWithAccess())); gp.setOpen_issues_count(p.getOpenIssuesCount()); gp.setForks_count(p.getForksCount()); gp.setLast_activity_at(lastActivity); diff --git a/src/main/java/at/ac/uibk/gitsearch/service/gitlab_events/ProjectPermissions.java b/src/main/java/at/ac/uibk/gitsearch/service/gitlab_events/ProjectPermissions.java index 04a09f3d61b721f2d2ac77b3cb3aa14a4cad51c2..d101b0692c9ad240e69b7fd6259b13e05a7a8ede 100644 --- a/src/main/java/at/ac/uibk/gitsearch/service/gitlab_events/ProjectPermissions.java +++ b/src/main/java/at/ac/uibk/gitsearch/service/gitlab_events/ProjectPermissions.java @@ -1,18 +1,25 @@ package at.ac.uibk.gitsearch.service.gitlab_events; -import java.util.ArrayList; -import java.util.List; +import java.util.*; public class ProjectPermissions { - final List<String> emailAddressesWithAccess = new ArrayList<>(); - final List<String> groupsWithAccess = new ArrayList<>(); + private final Set<String> emailAddressesWithAccess = new HashSet<>(); + private final Set<String> groupsWithAccess = new HashSet<>(); - public List<String> getEmailAddressesWithAccess() { + public void addEmailWithAccess(String email) { + this.emailAddressesWithAccess.add(email); + } + + public void addGroupWithAccess(String group) { + this.groupsWithAccess.add(group); + } + + public Set<String> getEmailAddressesWithAccess() { return emailAddressesWithAccess; } - public List<String> getGroupsWithAccess() { + public Set<String> getGroupsWithAccess() { return groupsWithAccess; } } diff --git a/src/test/java/at/ac/uibk/gitsearch/repository/search/testESService/ElasticSearchTestConfiguration.java b/src/test/java/at/ac/uibk/gitsearch/repository/search/testESService/ElasticSearchTestConfiguration.java index c9f2ee9e5add0b95295d32f707ca2d58b106fbde..6b8333448513c8fce61892f90579957d6ba8faaa 100644 --- a/src/test/java/at/ac/uibk/gitsearch/repository/search/testESService/ElasticSearchTestConfiguration.java +++ b/src/test/java/at/ac/uibk/gitsearch/repository/search/testESService/ElasticSearchTestConfiguration.java @@ -123,7 +123,7 @@ public class ElasticSearchTestConfiguration { } } esContainer = null; - LOGGER.warn("Shutted down ES Test Node"); + LOGGER.warn("Shut down ES Test Node"); } } diff --git a/src/test/java/at/ac/uibk/gitsearch/service/AuditEventServiceIT.java b/src/test/java/at/ac/uibk/gitsearch/service/AuditEventServiceIT.java index b13dc5f1b3c9f17822a0f2e951df09b68ea94023..abc8530ad26406cdb173594abf8962167df7fdc4 100644 --- a/src/test/java/at/ac/uibk/gitsearch/service/AuditEventServiceIT.java +++ b/src/test/java/at/ac/uibk/gitsearch/service/AuditEventServiceIT.java @@ -103,7 +103,7 @@ public class AuditEventServiceIT { @Test @Timeout(value = 5, unit = TimeUnit.MINUTES) @DirtiesContext - public void verifyOldAuditEventsAreDeleted() { + void verifyOldAuditEventsAreDeleted() { assertThat(persistenceAuditEventRepository.findAll().size()).isEqualTo(currentAuditLogs + auditEventsOld.size() + 2); log.info("Removing outdated AuditEvents"); @@ -124,7 +124,7 @@ public class AuditEventServiceIT { @Test @Timeout(value = 5, unit = TimeUnit.MINUTES) @DirtiesContext - public void verifyOldAuditEventsAreDeleted2() { + void verifyOldAuditEventsAreDeleted2() { assertThat(persistenceAuditEventRepository.findAll().size()).isEqualTo(currentAuditLogs + auditEventsOld.size() + 2); int deleted = this.auditEventService.removeOutdatedAuditEvents2(); diff --git a/src/test/java/at/ac/uibk/gitsearch/service/ReminderServiceIT.java b/src/test/java/at/ac/uibk/gitsearch/service/ReminderServiceIT.java index 9ab54cae51bbaea12703d705d37d03f4897eab1f..47da511d0ccc1b4363903ff21033c86cfa8d4711 100644 --- a/src/test/java/at/ac/uibk/gitsearch/service/ReminderServiceIT.java +++ b/src/test/java/at/ac/uibk/gitsearch/service/ReminderServiceIT.java @@ -225,9 +225,7 @@ public class ReminderServiceIT { verify(mailService).sendEmail(toCaptor.capture(), subjectCaptor.capture(), messageCaptor.capture(), anyBoolean(), anyBoolean()); assertThat(toCaptor.getValue()).contains(user.getEmail()); final String content = messageCaptor.getValue(); - assertThat(content).isNotEmpty(); - - assertThat(content).contains("Simple IO Test").contains("testDaily"); + assertThat(content).isNotEmpty().contains("Simple IO Test").contains("testDaily"); // last sending update? // for daily watch list diff --git a/src/test/java/at/ac/uibk/gitsearch/service/gitlab_events/GitlabEventServiceIT.java b/src/test/java/at/ac/uibk/gitsearch/service/gitlab_events/GitlabEventServiceIT.java index 9e2a84f95482c03fe2c6a20c6910ca016427a93b..dccf8270a975071419190f6aec4c25dc69a0c93f 100644 --- a/src/test/java/at/ac/uibk/gitsearch/service/gitlab_events/GitlabEventServiceIT.java +++ b/src/test/java/at/ac/uibk/gitsearch/service/gitlab_events/GitlabEventServiceIT.java @@ -10,6 +10,7 @@ import static org.mockito.Mockito.verify; import at.ac.uibk.gitsearch.GitsearchApp; import at.ac.uibk.gitsearch.repository.gitlab.GitLabRepository; import at.ac.uibk.gitsearch.repository.search.ElasticSearchRepository; +import at.ac.uibk.gitsearch.repository.search.MetaDataRepository; import at.ac.uibk.gitsearch.repository.search.SearchRepositoryConstants; import at.ac.uibk.gitsearch.repository.search.testESService.ElasticSearchTestConfiguration; import at.ac.uibk.gitsearch.service.MailService; @@ -28,8 +29,10 @@ import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; +import java.text.ParseException; import java.util.ArrayList; import java.util.List; +import java.util.Optional; import java.util.concurrent.TimeUnit; import java.util.stream.Stream; import javax.el.MethodNotFoundException; @@ -51,6 +54,8 @@ import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.core.userdetails.User; import org.springframework.security.test.context.support.WithMockUser; @SpringBootTest(classes = GitsearchApp.class) @@ -67,6 +72,9 @@ public class GitlabEventServiceIT { @Autowired protected GitlabEventService eventService; + @Autowired + protected MetaDataRepository metaDataRepository; + @MockBean private MailService mailService; @@ -107,6 +115,7 @@ public class GitlabEventServiceIT { .thenReturn(Boolean.TRUE); logger.info("starting handleGitLabEvent for {}", collectionCommitEvent); + eventService.handleGitLabEvent(collectionCommitEvent); eventService.waitForFinish(); logger.info("finished handleGitLabEvent for {}", collectionCommitEvent); @@ -114,6 +123,33 @@ public class GitlabEventServiceIT { // the example is correct :-) verify(mailService, Mockito.times(1)) .sendEmail(Mockito.eq("Michael.Breu@uibk.ac.at"), Mockito.anyString(), Mockito.anyString(), Mockito.eq(false), Mockito.eq(true)); + + // just reindex a second time, in order to check returned gitlab Id + eventService.handleGitLabEvent(collectionCommitEvent); + eventService.waitForFinish(); + } + + @Test + @Timeout(value = 30, unit = TimeUnit.MINUTES) + @WithMockUser(value = "Michael Breu", authorities = "teacher/unauthenticatedteachers") + void simplePermissionTest() throws StreamReadException, DatabindException, IOException, GitLabApiException, ParseException { + SystemHookEvent permissionCommitEvent = getPermissionCommitEvent(); + Mockito.reset(mailService); + Mockito + .when(mailService.sendEmail(Mockito.anyString(), Mockito.anyString(), Mockito.anyString(), Mockito.eq(false), Mockito.eq(true))) + .thenReturn(Boolean.TRUE); + + logger.info("starting permissionCommitEvent for {}", permissionCommitEvent); + eventService.handleGitLabEvent(permissionCommitEvent); + eventService.waitForFinish(); + + User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal(); + metaDataRepository.getExerciseById("[274]", Optional.of(user)); + + final SearchResultDTO exercise = metaDataRepository.getExerciseById("[274]", Optional.of(user)); + logger.info("finished permissionCommitEvent for {}", exercise); + assertThat(exercise.getProject().getGroups()).contains("teacher", "teacher/unauthenticatedteachers"); + assertThat(exercise.getProject().getUsers()).contains("simon.priller@uibk.ac.at"); } @Test @@ -190,6 +226,11 @@ public class GitlabEventServiceIT { return getTestSystemHookEvent(testEvent); } + private SystemHookEvent getPermissionCommitEvent() throws IOException { + final String testEvent = "testData/gitlabEvents/testInheritedPermissions.json"; + return getTestSystemHookEvent(testEvent); + } + private SystemHookEvent getMetaData5PushEvent() throws IOException { final String testEvent = "testData/gitlabEvents/metadataVersion5Test.json"; return getTestSystemHookEvent(testEvent); @@ -208,7 +249,7 @@ public class GitlabEventServiceIT { } @Test - @Timeout(value = 30, unit = TimeUnit.MINUTES) + @Timeout(value = 1, unit = TimeUnit.MINUTES) void simpleDeleteTest() throws StreamReadException, DatabindException, IOException, GitLabApiException, InterruptedException { assertThat(gitLabRepository.getAdminGitLabApi().getAuthToken()) .describedAs("This test requires a valid admin access token") diff --git a/src/test/resources/at/ac/uibk/gitsearch/service/gitlab_events/testData/gitlabEvents/testInheritedPermissions.json b/src/test/resources/at/ac/uibk/gitsearch/service/gitlab_events/testData/gitlabEvents/testInheritedPermissions.json new file mode 100644 index 0000000000000000000000000000000000000000..033e483d1c1a2a53d413571204f7daa6aefd82cb --- /dev/null +++ b/src/test/resources/at/ac/uibk/gitsearch/service/gitlab_events/testData/gitlabEvents/testInheritedPermissions.json @@ -0,0 +1,60 @@ +{ + "object_kind": "push", + "event_name": "push", + "before": "293b550d6089447f6b62b9a6abf7c318ec05cf86", + "after": "3baca63e5f21cf3cb680bce63bdeb34c6772f140", + "ref": "refs/heads/master", + "checkout_sha": "f9fbd3d3b520a3e59661f1806871db89294778de", + "message": null, + "user_id": 35, + "user_name": "Michael Breu", + "user_username": "c703257", + "user_email": "Michael.Breu@uibk.ac.at", + "user_avatar": "https://www.gravatar.com/avatar/ff28e10268b8c177179e17f11fd30357?s=80\u0026d=identicon", + "project_id": 274, + "project": { + "id": 274, + "name": "irrelvant", + "description": "", + "web_url": "https://sharing.codeability-austria.uibk.ac.at/sharing/health-check-tests/collection_tests/test1", + "avatar_url": null, + "git_ssh_url": "git@sharing.codeability-austria.uibk.ac.at:sharing/health-check-tests/collection_tests/testit2.git", + "git_http_url": "https://sharing.codeability-austria.uibk.ac.at/sharing/health-check-tests/collection_tests/test1.git", + "namespace": "sharing/health-check-tests/collection_tests", + "visibility_level": 0, + "path_with_namespace": "sharing/health-check-tests/collection_tests/testit2", + "default_branch": "master", + "ci_config_path": null, + "homepage": "http://sharing.codeability-austria.uibk.ac.at/sharing/health-check-tests/collection_tests/testit2", + "url": "git@sharing.codeability-austria.uibk.ac.at:sharing/health-check-tests/collection_tests/testit2.git", + "ssh_url": "git@sharing.codeability-austria.uibk.ac.at:sharing/health-check-tests/collection_tests/testit2.git", + "http_url": "http://sharing.codeability-austria.uibk.ac.at/sharing/health-check-tests/collection_tests/testit2.git" + }, + "commits": [ + { + "id": "3baca63e5f21cf3cb680bce63bdeb34c6772f140", + "message": "irrelevant: Update metadata.yaml", + "title": "irrelevant: Update metadata.yaml", + "timestamp": "2022-01-20T16:48:43+00:00", + "url": "https://sharing.codeability-austria.uibk.ac.at/sharing/health-check-tests/collection_tests/collectionstests1/-/commit/293b550d6089447f6b62b9a6abf7c318ec05cf86", + "author": { + "name": "Michael Breu", + "email": "Michael.Breu@uibk.ac.at" + }, + "added": [], + "modified": ["metadata.yaml"], + "removed": [] + } + ], + "total_commits_count": 1, + "push_options": {}, + "repository": { + "name": "CollectionTests1", + "url": "git@sharing.codeability-austria.uibk.ac.at:sharing/health-check-tests/collection_tests/collectionstests1.git", + "description": "", + "homepage": "http://sharing.codeability-austria.uibk.ac.at/sharing/health-check-tests/collection_tests/testit2", + "git_http_url": "http://sharing.codeability-austria.uibk.ac.at/sharing/health-check-tests/collection_tests/testit2.git", + "git_ssh_url": "git@sharing.codeability-austria.uibk.ac.at:sharing/health-check-tests/collection_tests/testit2.git", + "visibility_level": 0 + } +} diff --git a/src/test/sopaui/Sharing-Gitlab-Prod-soapui-project.xml b/src/test/sopaui/Sharing-Gitlab-Prod-soapui-project.xml new file mode 100644 index 0000000000000000000000000000000000000000..e707e640d55c7ff25abf6fec09974a43600b1f38 --- /dev/null +++ b/src/test/sopaui/Sharing-Gitlab-Prod-soapui-project.xml @@ -0,0 +1,2 @@ +<?xml version="1.0" encoding="UTF-8"?> +<con:soapui-project id="f15cb322-bca1-4f72-94c0-edce59dcf5e1" activeEnvironment="Default" name="Sharing Gitlab Prod" resourceRoot="" soapui-version="5.7.2" xmlns:con="http://eviware.com/soapui/config"><con:settings/><con:interface xsi:type="con:RestService" id="cab275c1-0fcf-470f-a5e4-6cfa80e2eec9" wadlVersion="http://wadl.dev.java.net/2009/02" name="https://sharing-codeability.uibk.ac.at" type="rest" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><con:settings/><con:definitionCache type="TEXT" rootPart=""/><con:endpoints><con:endpoint>https://sharing.codeability-austria.uibk.ac.at/api/v4</con:endpoint></con:endpoints><con:resource name="V4" path="/projects" id="219fb6b8-a1f2-4965-9e2e-ca42658fb80f"><con:settings/><con:parameters/><con:method name="V4 1" id="75d86bf4-6a49-4828-bc5c-3ea3a4dbb779" method="GET"><con:settings/><con:parameters/><con:representation type="RESPONSE"><con:mediaType>application/json</con:mediaType><con:status>200</con:status><con:params/><con:element>Response</con:element></con:representation><con:request name="Request 1" id="464de6e2-84ca-4136-af01-ef5a83c0867a" mediaType="application/json"><con:settings><con:setting id="com.eviware.soapui.impl.wsdl.WsdlRequest@request-headers"><xml-fragment/></con:setting></con:settings><con:endpoint>https://sharing.codeability-austria.uibk.ac.at/api/v4</con:endpoint><con:request/><con:originalUri>https://sharing-codeability.uibk.ac.at/api/v4/projects</con:originalUri><con:credentials><con:username xsi:nil="true"/><con:password xsi:nil="true"/><con:domain xsi:nil="true"/><con:authType>No Authorization</con:authType></con:credentials><con:jmsConfig JMSDeliveryMode="PERSISTENT"/><con:jmsPropertyConfig/><con:parameters/></con:request></con:method></con:resource><con:resource name="groups" path="/groups" id="dfc85de8-6522-4915-ac69-467c1406bc0a"><con:settings/><con:parameters/><con:method name="Method 1" id="ad310c54-c143-4d59-99d2-ba1efbe6b599" method="GET"><con:settings/><con:parameters/><con:representation type="RESPONSE"><con:mediaType>application/json</con:mediaType><con:status>200</con:status><con:params/><con:element>Response</con:element></con:representation><con:representation type="FAULT"><con:mediaType>application/json</con:mediaType><con:status>404</con:status><con:params/><con:element xmlns:gro="https://sharing-codeability.uibk.ac.at/api/v4/groups">gro:Fault</con:element></con:representation><con:request name="All Requests" id="e0aebed2-0440-4442-8641-781416db5140" mediaType="application/json"><con:settings><con:setting id="com.eviware.soapui.impl.wsdl.WsdlRequest@request-headers"><xml-fragment/></con:setting></con:settings><con:endpoint>https://sharing.codeability-austria.uibk.ac.at/api/v4</con:endpoint><con:request/><con:originalUri>https://sharing-codeability.uibk.ac.at/api/v4/groups</con:originalUri><con:credentials><con:username xsi:nil="true"/><con:password xsi:nil="true"/><con:domain xsi:nil="true"/><con:authType>No Authorization</con:authType></con:credentials><con:jmsConfig JMSDeliveryMode="PERSISTENT"/><con:jmsPropertyConfig/><con:parameters/></con:request><con:request name="GroupMembers" id="e0aebed2-0440-4442-8641-781416db5140" mediaType="application/json"><con:settings><con:setting id="com.eviware.soapui.impl.wsdl.WsdlRequest@request-headers"><xml-fragment/></con:setting></con:settings><con:endpoint>https://sharing.codeability-austria.uibk.ac.at/api/v4</con:endpoint><con:request/><con:originalUri>https://sharing-codeability.uibk.ac.at/api/v4/groups</con:originalUri><con:credentials><con:username xsi:nil="true"/><con:password xsi:nil="true"/><con:domain xsi:nil="true"/><con:authType>No Authorization</con:authType></con:credentials><con:jmsConfig JMSDeliveryMode="PERSISTENT"/><con:jmsPropertyConfig/><con:parameters/></con:request></con:method></con:resource></con:interface><con:properties><con:property><con:name>adminToken</con:name><con:value>glpat-HY-7PxnrfWfnE6WvX4YK</con:value></con:property></con:properties><con:wssContainer/><con:oAuth2ProfileContainer/><con:oAuth1ProfileContainer/><con:sensitiveInformation/></con:soapui-project> \ No newline at end of file