This is the codeAbility Sharing Platform! Learn more about the codeAbility Sharing Platform.

Skip to content
Snippets Groups Projects
Commit 78c3a194 authored by Michael Breu's avatar Michael Breu :speech_balloon:
Browse files

Merge branch '172-reduce-usage-of-gitlab-groups-in-gitsearch' into 'development'

Resolve "Reduce Usage of GitLab Groups in GitSearch"

See merge request sharing/codeability-sharing-platform!57
parents c3a6ca25 a37b8f6d
2 merge requests!62created achievementService and separated some functionality out of...,!57Resolve "Reduce Usage of GitLab Groups in GitSearch"
......@@ -149,7 +149,7 @@ public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
.deny()
.and()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.sessionCreationPolicy(SessionCreationPolicy.NEVER)
.and()
.authorizeRequests()
.antMatchers("/api/statistics/**").permitAll()
......
......@@ -67,4 +67,13 @@ public class Authority implements Serializable {
"name='" + name + '\'' +
"}";
}
public boolean isStandardRole() {
return isStandardRole(name);
}
public static boolean isStandardRole(String name) {
return name.startsWith("ROLE_");
}
}
......@@ -53,6 +53,7 @@ import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import at.ac.uibk.gitsearch.config.ApplicationProperties;
import at.ac.uibk.gitsearch.domain.Authority;
import at.ac.uibk.gitsearch.service.dto.AutoCompleteEntry;
@Repository
......@@ -439,7 +440,7 @@ public class MetaDataRepository {
final Collection<GrantedAuthority> authorities = user.get().getAuthorities();
final BoolQueryBuilder authQuery = QueryBuilders.boolQuery().boost(0.0f);
final Stream<QueryBuilder> prefixAuthQueries = authorities.stream()
.filter(auth -> !auth.getAuthority().startsWith("ROLE"))
.filter(auth -> !Authority.isStandardRole(auth.getAuthority()))
.filter(auth -> !auth.getAuthority().startsWith("SCOPE")).map(auth -> QueryBuilders
.prefixQuery(SearchRepositoryConstants.PROJECT_NAMESPACE, auth.getAuthority()));
prefixAuthQueries.forEach(pq -> authQuery.should(pq));
......@@ -585,7 +586,9 @@ public class MetaDataRepository {
exerciseId);
}
if (searchResponse.getHits().getHits().length > 0) {
return parseSearchHit(searchResponse.getHits().getHits()[0], objectMapper);
final SearchResultDTO parseSearchHit = parseSearchHit(searchResponse.getHits().getHits()[0], objectMapper);
parseSearchHit.setRanking5(5);
return parseSearchHit;
}
} catch (JsonProcessingException e) {
throw new NotFoundException(" Exercise with id " + exerciseId + " not found?", e);
......
package at.ac.uibk.gitsearch.security.oauth2;
import java.time.Instant;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.function.Consumer;
......@@ -18,6 +20,7 @@ import org.springframework.security.oauth2.core.OAuth2AccessToken;
import org.springframework.security.oauth2.core.oidc.user.OidcUser;
import org.springframework.stereotype.Component;
import at.ac.uibk.gitsearch.domain.Authority;
import at.ac.uibk.gitsearch.service.dto.UserDTO;
@Component
......@@ -50,10 +53,13 @@ public class UserDetailsFetcher {
gitLabApi.enableRequestResponseLogging();
// List<Project> memberProjects = gitLabApi.getProjectApi().getMemberProjects();
final Set<String> authorities = new HashSet<>();
authorities.addAll(u.getAuthorities());
// remove all old gitlab roles
u.getAuthorities().stream().filter(s -> Authority.isStandardRole(s)).forEach(authorities::add);
@SuppressWarnings("unchecked")
final List<String> gitLabGroups = (List<String>)oidcUser.getAttribute("groups");
authorities.addAll(gitLabGroups);
// add gitlab groups
authorities.addAll(reduceGroups(gitLabGroups)); // only add main groups
User gitUser = gitLabApi.getUserApi().getCurrentUser();
......@@ -77,6 +83,33 @@ public class UserDetailsFetcher {
return false;
}
/**
* unfortunatelly gitlab returns not only the main groups but also all groups in the project hierarchy. That makes the list
* very large. We need only the main groups!
* @param groups
* @return
*/
protected List<String> reduceGroups(List<String> groups) {
List<String> unNormalizedGroups = new ArrayList<String>(groups.size());
unNormalizedGroups.addAll(groups);
final Iterator<String> unNormalizedGroupsIterator = unNormalizedGroups.iterator();
while (unNormalizedGroupsIterator.hasNext()) {
String groupToCheck = unNormalizedGroupsIterator.next();
for(String otherGroup: unNormalizedGroups) {
if(groupToCheck.startsWith(otherGroup)) {
if(groupToCheck.length() == otherGroup.length()) // same group, just continue
continue;
if(groupToCheck.charAt(otherGroup.length()) == '/') { // it is a real subgroup
unNormalizedGroupsIterator.remove();
break;
}
}
}
}
return unNormalizedGroups; // now normalized :-)
}
private static boolean updateAttribute (String newString, String oldString, Consumer<String> setter) {
if(oldString==null) {
if(newString == null) return false;
......
......@@ -36,6 +36,7 @@ import {
faLanguage,
faDownload,
faTree,
faQuestion as farQuestion,
// jhipster-needle-add-icon-import
} from '@fortawesome/free-solid-svg-icons';
......@@ -80,6 +81,7 @@ export const fontAwesomeIcons = [
faBook,
faDownload,
faTree,
farQuestion,
// jhipster-needle-add-icon-import
];
......
......@@ -5,7 +5,7 @@ import { QueryParam, QueryParamBuilder, QueryParamGroup } from '@ngqp/core';
import { takeUntil } from 'rxjs/operators';
import { SearchInput } from 'app/shared/model/search/search-input.model';
import { SearchService } from '../service/search-service';
import { faQuestion, faTrash } from '@fortawesome/free-solid-svg-icons';
import { faQuestion, faTimes } from '@fortawesome/free-solid-svg-icons';
import { Observable } from 'rxjs';
import { debounceTime, distinctUntilChanged, map, switchMap } from 'rxjs/operators';
......@@ -31,7 +31,7 @@ export class SearchInputComponent implements OnInit, OnDestroy {
languageValues = Object.keys(ILanguages);
questionIcon = faQuestion;
crossIcon = faTrash;
crossIcon = faTimes;
public paramGroup: QueryParamGroup;
private componentDestroyed$ = new Subject<void>();
......@@ -139,6 +139,7 @@ export class SearchInputComponent implements OnInit, OnDestroy {
public clearParentId(): void {
this.searchInput.metadata.parentId = "";
this.paramGroup.queryParams["parentId"].setValue(null);
}
/*
......
package at.ac.uibk.gitsearch.security.oauth2;
import java.util.List;
import org.hamcrest.Matchers;
import org.junit.Assert;
import org.junit.jupiter.api.Test;
import com.google.common.collect.Lists;
class UserDetailsFetcherTest {
@Test
void testNormalizationWithRealExample() {
UserDetailsFetcher udf = new UserDetailsFetcher();
final List<String> realExample = Lists.newArrayList("sharing/university-innsbruck/c-exercises/eidp-21s",
"general1",
"sharing/graz-university-of-technology",
"internal",
"development",
"sharing/university-innsbruck/python/general",
"sharing/university-innsbruck/java",
"sharing/university-klagenfurt",
"sharing/university-salzburg",
"sharing/johannes-kepler-university-linz",
"sharing",
"sharing/danube-university-krems",
"development/sharing",
"sharing/university-innsbruck/python",
"sharing/vienna-university-of-technology",
"ROLE_USER",
"sharing/university-innsbruck/c-exercises",
"sharing/university-innsbruck/modelling",
"sharing/university-innsbruck",
"sharing/johannes-kepler-university-linz/java",
"ROLE_ADMIN",
"sharing/university-innsbruck/java/general");
Assert.assertThat(udf.reduceGroups(realExample), Matchers.containsInAnyOrder(
"general1",
"internal",
"development",
"sharing",
"ROLE_USER",
"ROLE_ADMIN"
));
}
@Test
void testNormalizationWithComplexExample() {
UserDetailsFetcher udf = new UserDetailsFetcher();
final List<String> complexExample = Lists.newArrayList("sharing/university-innsbruck/c-exercises/eidp-21s",
"sharing",
"sharing/university-innsbruck",
"sharing/university-innsbruck/java/general",
"sharing2/university-innsbruck/java/general");
Assert.assertThat(udf.reduceGroups(complexExample), Matchers.containsInAnyOrder(
"sharing",
"sharing2/university-innsbruck/java/general"
));
}
}
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment