1. update user authorities when adding/removing repositories

2. fixed some authorization expressions
3. refactoring
This commit is contained in:
Konstantinos Spyrou 2021-07-06 13:31:27 +00:00
parent f05ccb0b43
commit 7b9e1ef4a7
8 changed files with 146 additions and 122 deletions

View File

@ -4,6 +4,8 @@ import com.google.gson.JsonArray;
import com.google.gson.JsonElement; import com.google.gson.JsonElement;
import eu.dnetlib.repo.manager.domain.dto.Role; import eu.dnetlib.repo.manager.domain.dto.Role;
import eu.dnetlib.repo.manager.service.aai.registry.AaiRegistryService; import eu.dnetlib.repo.manager.service.aai.registry.AaiRegistryService;
import eu.dnetlib.repo.manager.service.security.AaiUserRoleService;
import eu.dnetlib.repo.manager.service.security.AuthoritiesUpdater;
import eu.dnetlib.repo.manager.utils.JsonUtils; import eu.dnetlib.repo.manager.utils.JsonUtils;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
@ -26,17 +28,16 @@ import java.util.List;
public class AaiUserRoleController { public class AaiUserRoleController {
private final AaiRegistryService aaiRegistryService; private final AaiRegistryService aaiRegistryService;
private final AuthoritiesUpdater authoritiesUpdater;
// TODO: Antonis K. This should be uncommented private final AaiUserRoleService aaiUserRoleService;
// @Autowired
// private AuthoritiesUpdater authoritiesUpdater;
//
// @Autowired
// private AuthorizationService authorizationService;
@Autowired @Autowired
AaiUserRoleController(AaiRegistryService aaiRegistryService) { AaiUserRoleController(AaiRegistryService aaiRegistryService,
AuthoritiesUpdater authoritiesUpdater,
AaiUserRoleService aaiUserRoleService) {
this.aaiRegistryService = aaiRegistryService; this.aaiRegistryService = aaiRegistryService;
this.authoritiesUpdater = authoritiesUpdater;
this.aaiUserRoleService = aaiUserRoleService;
} }
private String sendEmail() { private String sendEmail() {
@ -45,10 +46,10 @@ public class AaiUserRoleController {
} }
/** /**
* Create a new role with the given name and description. * Get the role with the given name and description.
**/ **/
@RequestMapping(method = RequestMethod.GET, path = "/role/id/get") @RequestMapping(method = RequestMethod.GET, path = "/role/id/get")
// @PreAuthorize("hasAnyAuthority('ROLE_USER', 'ROLE_ADMIN', 'ROLE_PROVIDE_ADMIN')") // TODO: Perhaps less roles here // @PreAuthorize("hasAnyAuthority('ROLE_USER', 'ROLE_ADMIN', 'ROLE_PROVIDE_ADMIN')")
public Response getRole(@RequestParam(value = "type", defaultValue = "datasource") String type, @RequestParam("id") String id) { public Response getRole(@RequestParam(value = "type", defaultValue = "datasource") String type, @RequestParam("id") String id) {
int roleId = aaiRegistryService.getCouId(type, id); int roleId = aaiRegistryService.getCouId(type, id);
return Response.status(HttpStatus.OK.value()).entity(JsonUtils.createResponse("Role id is: " + roleId).toString()).type(MediaType.APPLICATION_JSON).build(); return Response.status(HttpStatus.OK.value()).entity(JsonUtils.createResponse("Role id is: " + roleId).toString()).type(MediaType.APPLICATION_JSON).build();
@ -58,7 +59,7 @@ public class AaiUserRoleController {
* Create a new role with the given name and description. * Create a new role with the given name and description.
**/ **/
@RequestMapping(method = RequestMethod.POST, path = "/createRole") @RequestMapping(method = RequestMethod.POST, path = "/createRole")
@PreAuthorize("hasAnyAuthority('ROLE_USER', 'ROLE_ADMIN', 'ROLE_PROVIDE_ADMIN')") // TODO: Perhaps less roles here @PreAuthorize("hasAnyAuthority('ROLE_ADMIN')")
public Response createRole(@RequestBody Role role) { public Response createRole(@RequestBody Role role) {
aaiRegistryService.createRole(role); aaiRegistryService.createRole(role);
return Response.status(HttpStatus.OK.value()).entity(JsonUtils.createResponse("Role has been created").toString()).type(MediaType.APPLICATION_JSON).build(); return Response.status(HttpStatus.OK.value()).entity(JsonUtils.createResponse("Role has been created").toString()).type(MediaType.APPLICATION_JSON).build();
@ -69,8 +70,7 @@ public class AaiUserRoleController {
*/ */
@ApiOperation(value = "subscribe") @ApiOperation(value = "subscribe")
@RequestMapping(method = RequestMethod.POST, path = "/subscribe/{type}/{id}") @RequestMapping(method = RequestMethod.POST, path = "/subscribe/{type}/{id}")
@PreAuthorize("hasAnyAuthority('ROLE_ADMIN', 'ROLE_PROVIDE_ADMIN') or (hasRole(@Converter.convertRepoIdToRoleId(#repository.id)) or hasRole(@Converter.convertRepoIdToRoleId(returnObject.id)))") @PreAuthorize("hasAnyAuthority('ROLE_ADMIN', 'ROLE_PROVIDE_ADMIN')")
// TODO: Perhaps less roles here
public Response subscribe(@PathVariable("type") String type, @PathVariable("id") String id) { public Response subscribe(@PathVariable("type") String type, @PathVariable("id") String id) {
Integer coPersonId = aaiRegistryService.getCoPersonIdByIdentifier(); Integer coPersonId = aaiRegistryService.getCoPersonIdByIdentifier();
if (coPersonId == null) { if (coPersonId == null) {
@ -80,12 +80,10 @@ public class AaiUserRoleController {
if (couId != null) { if (couId != null) {
Integer role = aaiRegistryService.getRoleId(coPersonId, couId); Integer role = aaiRegistryService.getRoleId(coPersonId, couId);
aaiRegistryService.assignMemberRole(coPersonId, couId, role); aaiRegistryService.assignMemberRole(coPersonId, couId, role);
// TODO: Antonis K. This should be uncommented to make a role DATASOURCE.OP... for every new repo
// authoritiesUpdater.update(sendEmail(), old -> { // Add role to current user authorities
// HashSet<SimpleGrantedAuthority> authorities = new HashSet<>((Collection<? extends SimpleGrantedAuthority>) old); authoritiesUpdater.addRole(aaiUserRoleService.convertRepoIdToAuthority(id));
// authorities.add(new SimpleGrantedAuthority(authorizationService.member(type, id)));
// return authorities;
// });
return Response.status(HttpStatus.OK.value()).entity(JsonUtils.createResponse("Role has been assigned").toString()).type(MediaType.APPLICATION_JSON).build(); return Response.status(HttpStatus.OK.value()).entity(JsonUtils.createResponse("Role has been assigned").toString()).type(MediaType.APPLICATION_JSON).build();
} else { } else {
return Response.status(HttpStatus.NOT_FOUND.value()).entity(JsonUtils.createResponse("Role has not been found").toString()).type(MediaType.APPLICATION_JSON).build(); return Response.status(HttpStatus.NOT_FOUND.value()).entity(JsonUtils.createResponse("Role has not been found").toString()).type(MediaType.APPLICATION_JSON).build();
@ -98,7 +96,7 @@ public class AaiUserRoleController {
*/ */
@ApiOperation(value = "Remove role from member") @ApiOperation(value = "Remove role from member")
@RequestMapping(method = RequestMethod.DELETE, path = "/{type}/{id}/member/{email}") @RequestMapping(method = RequestMethod.DELETE, path = "/{type}/{id}/member/{email}")
@PreAuthorize("hasAnyAuthority('ROLE_USER', 'ROLE_ADMIN', 'ROLE_PROVIDE_ADMIN')") // TODO: Perhaps less roles here @PreAuthorize("hasAnyAuthority('ROLE_ADMIN', 'ROLE_PROVIDE_ADMIN')") // FIXME: ??
public Response removeMemberRole(@PathVariable("type") String type, @PathVariable("id") String public Response removeMemberRole(@PathVariable("type") String type, @PathVariable("id") String
id, @PathVariable("email") String email) { id, @PathVariable("email") String email) {
Integer coPersonId = aaiRegistryService.getCoPersonIdByEmail(email); Integer coPersonId = aaiRegistryService.getCoPersonIdByEmail(email);
@ -110,12 +108,10 @@ public class AaiUserRoleController {
} }
if (couId != null && role != null) { if (couId != null && role != null) {
aaiRegistryService.removeMemberRole(coPersonId, couId, role); aaiRegistryService.removeMemberRole(coPersonId, couId, role);
// TODO: Antonis K. This should be uncommented to make a role DATASOURCE.OP... for every new repo
// authoritiesUpdater.update(email, old -> { // Remove role from current user authorities
// HashSet<SimpleGrantedAuthority> authorities = new HashSet<>((Collection<? extends SimpleGrantedAuthority>) old); authoritiesUpdater.removeRole(aaiUserRoleService.convertRepoIdToAuthority(id));
// authorities.remove(new SimpleGrantedAuthority(authorizationService.member(type, id)));
// return authorities;
// });
return Response.status(HttpStatus.OK.value()).entity(JsonUtils.createResponse("Role has been removed").toString()).type(MediaType.APPLICATION_JSON).build(); return Response.status(HttpStatus.OK.value()).entity(JsonUtils.createResponse("Role has been removed").toString()).type(MediaType.APPLICATION_JSON).build();
} else { } else {
return Response.status(HttpStatus.NOT_FOUND.value()).entity(JsonUtils.createResponse("Role has not been found").toString()).type(MediaType.APPLICATION_JSON).build(); return Response.status(HttpStatus.NOT_FOUND.value()).entity(JsonUtils.createResponse("Role has not been found").toString()).type(MediaType.APPLICATION_JSON).build();
@ -130,7 +126,7 @@ public class AaiUserRoleController {
* Subscribe to role-repo by his email * Subscribe to role-repo by his email
*/ */
@RequestMapping(method = RequestMethod.POST, path = "/subscribe/repo-role/{id}") @RequestMapping(method = RequestMethod.POST, path = "/subscribe/repo-role/{id}")
@PreAuthorize("hasAnyAuthority('ROLE_USER', 'ROLE_ADMIN', 'ROLE_PROVIDE_ADMIN')") // TODO: Perhaps less roles here @PreAuthorize("hasAnyAuthority('ROLE_ADMIN', 'ROLE_PROVIDE_ADMIN') or @aaiUserRoleService.isMemberOf(#id)")
public Response subscribeRoleByEmail(@PathVariable("id") String id, @RequestParam("email") String email) { public Response subscribeRoleByEmail(@PathVariable("id") String id, @RequestParam("email") String email) {
Integer coPersonId = aaiRegistryService.getCoPersonIdByEmail(email); Integer coPersonId = aaiRegistryService.getCoPersonIdByEmail(email);
if (coPersonId != null) { if (coPersonId != null) {
@ -138,12 +134,10 @@ public class AaiUserRoleController {
if (couId != null) { if (couId != null) {
Integer role = aaiRegistryService.getRoleId(coPersonId, couId); Integer role = aaiRegistryService.getRoleId(coPersonId, couId);
aaiRegistryService.assignMemberRole(coPersonId, couId, role); aaiRegistryService.assignMemberRole(coPersonId, couId, role);
// TODO: Antonis K. This should be uncommented to make a role DATASOURCE.OP... for every new repo
// authoritiesUpdater.update(sendEmail(), old -> { // Add role to current user authorities
// HashSet<SimpleGrantedAuthority> authorities = new HashSet<>((Collection<? extends SimpleGrantedAuthority>) old); authoritiesUpdater.addRole(aaiUserRoleService.convertRepoIdToAuthority(id));
// authorities.add(new SimpleGrantedAuthority(authorizationService.member("datasource", id)));
// return authorities;
// });
return Response.status(HttpStatus.OK.value()).entity(JsonUtils.createResponse("Role has been assigned").toString()).type(MediaType.APPLICATION_JSON).build(); return Response.status(HttpStatus.OK.value()).entity(JsonUtils.createResponse("Role has been assigned").toString()).type(MediaType.APPLICATION_JSON).build();
} else { } else {
return Response.status(HttpStatus.NOT_FOUND.value()).entity(JsonUtils.createResponse("Role has not been found").toString()).type(MediaType.APPLICATION_JSON).build(); return Response.status(HttpStatus.NOT_FOUND.value()).entity(JsonUtils.createResponse("Role has not been found").toString()).type(MediaType.APPLICATION_JSON).build();
@ -160,7 +154,7 @@ public class AaiUserRoleController {
* Get all the users that have the role that is associated with repoId * Get all the users that have the role that is associated with repoId
*/ */
@RequestMapping(method = RequestMethod.GET, path = "/repo/{id}/all-users") @RequestMapping(method = RequestMethod.GET, path = "/repo/{id}/all-users")
@PreAuthorize("hasAnyAuthority('ROLE_USER', 'ROLE_ADMIN', 'ROLE_PROVIDE_ADMIN')") // TODO: Perhaps less roles here @PreAuthorize("hasAnyAuthority('ROLE_ADMIN', 'ROLE_PROVIDE_ADMIN')") // FIXME: ??
public ResponseEntity<List<String>> getAllUsersOfARepo(@PathVariable("id") String id) { public ResponseEntity<List<String>> getAllUsersOfARepo(@PathVariable("id") String id) {
List<String> userList = new ArrayList<>(); List<String> userList = new ArrayList<>();
@ -181,7 +175,7 @@ public class AaiUserRoleController {
///////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////
@RequestMapping(method = RequestMethod.GET, path = "/users/couid/{id}") @RequestMapping(method = RequestMethod.GET, path = "/users/couid/{id}")
@PreAuthorize("hasAnyAuthority('ROLE_USER', 'ROLE_ADMIN', 'ROLE_PROVIDE_ADMIN')") @PreAuthorize("hasAnyAuthority('ROLE_ADMIN', 'ROLE_PROVIDE_ADMIN')")
public ResponseEntity<String> getUsersByCouId(@PathVariable("id") Integer id) { public ResponseEntity<String> getUsersByCouId(@PathVariable("id") Integer id) {
// calls.getUserByCoId() // calls.getUserByCoId()
return ResponseEntity.ok(aaiRegistryService.getUsersByCouId(id).toString()); return ResponseEntity.ok(aaiRegistryService.getUsersByCouId(id).toString());
@ -189,7 +183,7 @@ public class AaiUserRoleController {
@RequestMapping(method = RequestMethod.GET, path = "/user/roles") @RequestMapping(method = RequestMethod.GET, path = "/user/roles")
@PreAuthorize("hasAnyAuthority('ROLE_USER', 'ROLE_ADMIN', 'ROLE_PROVIDE_ADMIN')") @PreAuthorize("hasAnyAuthority('ROLE_ADMIN', 'ROLE_PROVIDE_ADMIN') or hasRole('ROLE_USER') and authentication.userInfo.email==#email")
public ResponseEntity<List<String>> getRolesByEmail(@RequestParam("email") String email) { public ResponseEntity<List<String>> getRolesByEmail(@RequestParam("email") String email) {
int coPersonId = aaiRegistryService.getCoPersonIdByEmail(email); int coPersonId = aaiRegistryService.getCoPersonIdByEmail(email);
List<String> list = new ArrayList<>(); List<String> list = new ArrayList<>();

View File

@ -6,7 +6,6 @@ import eu.dnetlib.repo.manager.domain.OrderByType;
import eu.dnetlib.repo.manager.domain.Paging; import eu.dnetlib.repo.manager.domain.Paging;
import eu.dnetlib.repo.manager.domain.RepositoryServiceException; import eu.dnetlib.repo.manager.domain.RepositoryServiceException;
import eu.dnetlib.repo.manager.service.PiWikServiceImpl; import eu.dnetlib.repo.manager.service.PiWikServiceImpl;
import eu.dnetlib.repo.manager.service.RepositoryService;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam; import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams; import io.swagger.annotations.ApiImplicitParams;
@ -40,20 +39,16 @@ public class PiWikController {
@Autowired @Autowired
private PiWikServiceImpl piWikService; private PiWikServiceImpl piWikService;
@Autowired
private RepositoryService repositoryService;
// TODO: Antonis K. - replace here the registeredBy
@RequestMapping(value = "/getPiwikSiteForRepo/{repositoryId}" , method = RequestMethod.GET,produces = MediaType.APPLICATION_JSON_VALUE) @RequestMapping(value = "/getPiwikSiteForRepo/{repositoryId}" , method = RequestMethod.GET,produces = MediaType.APPLICATION_JSON_VALUE)
@ResponseBody @ResponseBody
@PreAuthorize("hasRole('ROLE_ADMIN') or hasRole('ROLE_PROVIDE_ADMIN') or ((@repositoryService.getRepositoryById(#repositoryId).registeredBy==authentication.userInfo.email or @repositoryService.getRepositoryById(#repositoryId).registeredBy=='null') and hasRole('ROLE_USER'))") @PreAuthorize("hasAnyRole('ROLE_ADMIN', 'ROLE_PROVIDE_ADMIN') or @aaiUserRoleService.isMemberOf(#repositoryId) or (@repositoryService.getRepositoryById(#repositoryId).registeredBy=='null' and hasRole('ROLE_USER'))")
public PiwikInfo getPiwikSiteForRepo(@PathVariable("repositoryId") String repositoryId) { public PiwikInfo getPiwikSiteForRepo(@PathVariable("repositoryId") String repositoryId) {
return piWikService.getPiwikSiteForRepo(repositoryId); return piWikService.getPiwikSiteForRepo(repositoryId);
} }
@RequestMapping(value = "/savePiwikInfo" , method = RequestMethod.POST,produces = MediaType.APPLICATION_JSON_VALUE) @RequestMapping(value = "/savePiwikInfo" , method = RequestMethod.POST,produces = MediaType.APPLICATION_JSON_VALUE)
@PreAuthorize("hasRole('ROLE_ADMIN') or hasRole('ROLE_PROVIDE_ADMIN') or ((@repositoryService.getRepositoryById(#piwikInfo.repositoryId).registeredBy==authentication.userInfo.email or @repositoryService.getRepositoryById(#piwikInfo.repositoryId).registeredBy=='null') and hasRole('ROLE_USER'))") @PreAuthorize("hasAnyRole('ROLE_ADMIN', 'ROLE_PROVIDE_ADMIN') or @aaiUserRoleService.isMemberOf(#piwikInfo.repositoryId) or (@repositoryService.getRepositoryById(#piwikInfo.repositoryId).registeredBy=='null' and hasRole('ROLE_USER'))")
public PiwikInfo savePiwikInfo(@RequestBody PiwikInfo piwikInfo) { public PiwikInfo savePiwikInfo(@RequestBody PiwikInfo piwikInfo) {
return piWikService.savePiwikInfo(piwikInfo); return piWikService.savePiwikInfo(piwikInfo);
} }
@ -162,7 +157,7 @@ public class PiWikController {
@RequestMapping(value = "/getOpenaireId/{repositoryId}" , method = RequestMethod.GET,produces = MediaType.APPLICATION_JSON_VALUE) @RequestMapping(value = "/getOpenaireId/{repositoryId}" , method = RequestMethod.GET,produces = MediaType.APPLICATION_JSON_VALUE)
@ResponseBody @ResponseBody
@PreAuthorize("hasRole('ROLE_ADMIN') or hasRole('ROLE_PROVIDE_ADMIN') or ((@repositoryService.getRepositoryById(#repositoryId).registeredBy==authentication.userInfo.email or @repositoryService.getRepositoryById(#repositoryId).registeredBy=='null') and hasRole('ROLE_USER'))") @PreAuthorize("hasAnyRole('ROLE_ADMIN', 'ROLE_PROVIDE_ADMIN') or @aaiUserRoleService.isMemberOf(#repositoryId) or (@repositoryService.getRepositoryById(#repositoryId).registeredBy=='null' and hasRole('ROLE_USER'))")
public String getOpenaireId(@PathVariable("repositoryId") String repositoryId){ public String getOpenaireId(@PathVariable("repositoryId") String repositoryId){
return piWikService.getOpenaireId(repositoryId); return piWikService.getOpenaireId(repositoryId);
} }

View File

@ -11,6 +11,7 @@ import org.json.JSONException;
import org.mitre.openid.connect.model.OIDCAuthenticationToken; import org.mitre.openid.connect.model.OIDCAuthenticationToken;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType; import org.springframework.http.MediaType;
import org.springframework.security.access.prepost.PostAuthorize;
import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.Authentication; import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.core.context.SecurityContextHolder;
@ -82,12 +83,11 @@ public class RepositoryController {
return repositoryService.searchRegisteredRepositories(country, typology, englishName, officialName, requestSortBy, order, page, pageSize); return repositoryService.searchRegisteredRepositories(country, typology, englishName, officialName, requestSortBy, order, page, pageSize);
} }
// TODO: Antonis K - Replace here the registeredBy
@RequestMapping(value = "/getRepositoryById/{id}", method = RequestMethod.GET, @RequestMapping(value = "/getRepositoryById/{id}", method = RequestMethod.GET,
produces = MediaType.APPLICATION_JSON_VALUE) produces = MediaType.APPLICATION_JSON_VALUE)
@ResponseBody @ResponseBody
@PreAuthorize("hasRole('ROLE_ADMIN') or hasRole('ROLE_PROVIDE_ADMIN') or @aaiUserRoleService.isMemberOf(#id)") @PostAuthorize("hasAnyRole('ROLE_ADMIN', 'ROLE_PROVIDE_ADMIN') or @aaiUserRoleService.isMemberOf(#id) or (returnObject.registeredBy=='null' and hasRole('ROLE_USER'))")
public Repository getRepositoryById(@PathVariable("id") String id) throws JSONException, ResourceNotFoundException { public Repository getRepositoryById(@PathVariable("id") String id) throws JSONException, ResourceNotFoundException {
Repository repo = repositoryService.getRepositoryById(id); Repository repo = repositoryService.getRepositoryById(id);
@ -137,10 +137,6 @@ public class RepositoryController {
public Repository addRepository(@RequestParam("datatype") String datatype, public Repository addRepository(@RequestParam("datatype") String datatype,
@RequestBody Repository repository) throws Exception { @RequestBody Repository repository) throws Exception {
// TODO:
// 1) add repository
// 2) get repository id and create new role
// 3) assign new role to authenticated user
return repositoryService.addRepository(datatype, repository); return repositoryService.addRepository(datatype, repository);
} }

View File

@ -13,7 +13,8 @@ import eu.dnetlib.repo.manager.domain.*;
import eu.dnetlib.repo.manager.domain.dto.Role; import eu.dnetlib.repo.manager.domain.dto.Role;
import eu.dnetlib.repo.manager.exception.ResourceNotFoundException; import eu.dnetlib.repo.manager.exception.ResourceNotFoundException;
import eu.dnetlib.repo.manager.service.aai.registry.AaiRegistryService; import eu.dnetlib.repo.manager.service.aai.registry.AaiRegistryService;
import eu.dnetlib.repo.manager.service.security.AuthorizationService; import eu.dnetlib.repo.manager.service.security.AaiUserRoleService;
import eu.dnetlib.repo.manager.service.security.AuthoritiesUpdater;
import eu.dnetlib.repo.manager.utils.Converter; import eu.dnetlib.repo.manager.utils.Converter;
import gr.uoa.di.driver.enabling.vocabulary.VocabularyLoader; import gr.uoa.di.driver.enabling.vocabulary.VocabularyLoader;
import org.apache.commons.codec.digest.DigestUtils; import org.apache.commons.codec.digest.DigestUtils;
@ -24,12 +25,15 @@ import org.json.JSONObject;
import org.mitre.openid.connect.model.OIDCAuthenticationToken; import org.mitre.openid.connect.model.OIDCAuthenticationToken;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Lazy;
import org.springframework.core.ParameterizedTypeReference; import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.*; import org.springframework.http.*;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.security.core.Authentication; import org.springframework.security.core.Authentication;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.web.client.HttpClientErrorException;
import org.springframework.web.client.RestClientException; import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate; import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponents; import org.springframework.web.util.UriComponents;
@ -45,58 +49,58 @@ import java.util.stream.Collectors;
@Service("repositoryService") @Service("repositoryService")
public class RepositoryServiceImpl implements RepositoryService { public class RepositoryServiceImpl implements RepositoryService {
private static final Logger LOGGER = Logger.getLogger(RepositoryServiceImpl.class);
private final AaiUserRoleService aaiUserRoleService;
private final AaiRegistryService registryCalls;
private final AuthoritiesUpdater authoritiesUpdater;
private final RestTemplate restTemplate;
private final VocabularyLoader vocabularyLoader;
private final PiWikService piWikService;
private final EmailUtils emailUtils;
private final ValidatorService validatorService;
@Value("${api.baseAddress}") @Value("${api.baseAddress}")
private String baseAddress; private String baseAddress;
@Value("${services.repo-manager.adminEmail}") @Value("${services.repo-manager.adminEmail}")
private String adminEmail; private String adminEmail;
@Autowired
RestTemplate restTemplate;
private HttpHeaders httpHeaders;
private final String[] vocabularyNames = {"dnet:countries", "dnet:datasource_typologies", "dnet:compatibilityLevel"};
private static final Logger LOGGER = Logger.getLogger(RepositoryServiceImpl.class);
@Value("${services.repomanager.usageStatisticsDiagramsBaseURL}") @Value("${services.repomanager.usageStatisticsDiagramsBaseURL}")
private String usageStatisticsDiagramsBaseURL; private String usageStatisticsDiagramsBaseURL;
@Value("${services.repomanager.usageStatisticsNumbersBaseURL}") @Value("${services.repomanager.usageStatisticsNumbersBaseURL}")
private String usageStatisticsNumbersBaseURL; private String usageStatisticsNumbersBaseURL;
@Autowired
private VocabularyLoader vocabularyLoader; private static final Map<String, List<String>> dataSourceClass = new HashMap<>();
private static final Map<String, String> invertedDataSourceClass = new HashMap<>();
private final String[] vocabularyNames = {"dnet:countries", "dnet:datasource_typologies", "dnet:compatibilityLevel"};
private final Map<String, Vocabulary> vocabularyMap = new ConcurrentHashMap<>();
private final Map<String, String> countriesMap = new HashMap<>();
private final Map<String, String> inverseCountriesMap = new HashMap<>();
private HttpHeaders httpHeaders;
@Autowired @Autowired
private PiWikService piWikService; public RepositoryServiceImpl(AaiUserRoleService aaiUserRoleService,
AaiRegistryService registryCalls,
@Autowired AuthoritiesUpdater authoritiesUpdater,
private EmailUtils emailUtils; VocabularyLoader vocabularyLoader, EmailUtils emailUtils,
RestTemplate restTemplate,
@Autowired @Lazy ValidatorService validatorService,
ValidatorService validatorService; @Lazy PiWikService piWikService) {
this.aaiUserRoleService = aaiUserRoleService;
@Autowired this.registryCalls = registryCalls;
private AaiRegistryService registryCalls; this.authoritiesUpdater = authoritiesUpdater;
this.vocabularyLoader = vocabularyLoader;
// TODO: Antonis K. This should be uncommented this.piWikService = piWikService;
// @Autowired this.emailUtils = emailUtils;
// private AuthoritiesUpdater authoritiesUpdater; this.validatorService = validatorService;
this.restTemplate = restTemplate;
@Autowired }
private AuthorizationService authorizationService;
private Map<String, Vocabulary> vocabularyMap = new ConcurrentHashMap<>();
private Map<String, String> countriesMap = new HashMap<>();
private Map<String, String> inverseCountriesMap = new HashMap<>();
private static Map<String, List<String>> dataSourceClass = new HashMap<>();
private static Map<String, String> invertedDataSourceClass = new HashMap<>();
private String sendEmail() { private String sendEmail() {
OIDCAuthenticationToken authenticationToken = (OIDCAuthenticationToken) SecurityContextHolder.getContext().getAuthentication(); OIDCAuthenticationToken authenticationToken = (OIDCAuthenticationToken) SecurityContextHolder.getContext().getAuthentication();
@ -508,31 +512,32 @@ public class RepositoryServiceImpl implements RepositoryService {
this.latentUpdate(repository, SecurityContextHolder.getContext().getAuthentication()); this.latentUpdate(repository, SecurityContextHolder.getContext().getAuthentication());
} }
// TODO: Antonis K. - Create new role ROLE_(datasource.datasourceId) and assign it to the user that created the folder (+ replace :: with $$) // TODO: move the following code elsewhere (creation and assignment of role to user) ??
// Create new role ( careful ... replace :: with $$ ) // Create new role
String newRoleName = repository.getId().replaceAll(":", "\\$"); String newRoleName = aaiUserRoleService.getRoleIdByRepoId(repository.getId());
String newRoleDescr = repository.getId().replaceAll(":", "\\$"); Role newRole = new Role(newRoleName, repository.getOfficialName());
Role newRole = new Role(newRoleName, newRoleDescr); Integer couId = null;
try { try {
registryCalls.createRole(newRole); couId = registryCalls.createRole(newRole);
} catch (HttpClientErrorException e) {
couId = registryCalls.getCouId(newRoleName);
if (couId == null) {
LOGGER.error(String.format("Could not create role '%s'", newRoleName), e);
}
} catch (Exception e) { } catch (Exception e) {
LOGGER.debug("Exception on create role during add repository", e); LOGGER.error(String.format("Could not create role '%s'", newRoleName), e);
throw e; throw e;
} }
// Assign new role to the user that created it // Assign new role to the user that created it
Integer coPersonId = registryCalls.getCoPersonIdByIdentifier(); Integer coPersonId = registryCalls.getCoPersonIdByIdentifier();
Integer couId = registryCalls.getCouId("datasource", newRoleName);
if (couId != null) { if (couId != null) {
Integer role = registryCalls.getRoleId(coPersonId, couId); Integer role = registryCalls.getRoleId(coPersonId, couId);
try { try {
registryCalls.assignMemberRole(coPersonId, couId, role); registryCalls.assignMemberRole(coPersonId, couId, role);
// TODO: Antonis K. This should be uncommented to make a role DATASOURCE.OP... for every new repo
// authoritiesUpdater.update(sendEmail(), old -> { // Add role to current user authorities
// HashSet<SimpleGrantedAuthority> authorities = new HashSet<>((Collection<? extends SimpleGrantedAuthority>) old); authoritiesUpdater.addRole(aaiUserRoleService.convertRepoIdToAuthority(repository.getId()));
// authorities.add(new SimpleGrantedAuthority(authorizationService.member("datasource", newRoleName)));
// return authorities;
// });
} catch (Exception e) { } catch (Exception e) {
LOGGER.debug("Exception on assign role to user during add repository", e); LOGGER.debug("Exception on assign role to user during add repository", e);
throw e; throw e;

View File

@ -12,33 +12,34 @@ public interface AaiUserRoleService {
String getRepoNameWithoutType(String fullName, String prefix); String getRepoNameWithoutType(String fullName, String prefix);
/** /**
* @param repoId * @param repoId Repository Id
* @param prefix * @return Converts {@param repoId} to a role Id.
* @return
*/ */
String getRoleIdByRepoId(String repoId, String prefix); String getRoleIdByRepoId(String repoId);
/** /**
* @param repoId * @param repoId Repository Id
* @return * @return
*/ */
String convertRepoIdToAuthorityId(String repoId); String convertRepoIdToAuthorityId(String repoId);
/** /**
* @param repoId * @param repoId Repository Id
* @return * @return Converts {@param repoId} to {@link String} role id url encoded ($ -> %24)
* // TODO: remove role encoding and perform url decoding when mapping authorities. (Must be performed in all OpenAIRE projects because of Redis)
*/ */
String convertRepoIdToEncodedAuthorityId(String repoId); String convertRepoIdToEncodedAuthorityId(String repoId);
/** /**
* @param repoId * @param repoId Repository Id
* @return * @return Converts {@param repoId} to {@link SimpleGrantedAuthority} with the role url encoded ($ -> %24)
* // TODO: remove role encoding and perform url decoding when mapping authorities. (Must be performed in all OpenAIRE projects because of Redis)
*/ */
SimpleGrantedAuthority convertRepoIdToAuthority(String repoId); SimpleGrantedAuthority convertRepoIdToAuthority(String repoId);
/** /**
* @param repoId * @param repoId Repository Id to check.
* @return * @return Checks if a user is a member of a repository or not.
*/ */
boolean isMemberOf(String repoId); boolean isMemberOf(String repoId);

View File

@ -30,9 +30,10 @@ public class AaiUserRoleServiceImpl implements AaiUserRoleService {
} }
@Override @Override
public String getRoleIdByRepoId(String repoId, String prefix) { public String getRoleIdByRepoId(String repoId) {
String roleId = ""; String roleId = "";
if (repoId != null && prefix != null) { String prefix = production ? null : "beta." + "datasource";
if (repoId != null) {
roleId = createRepoRoleName(prefix, repoId); roleId = createRepoRoleName(prefix, repoId);
return roleId; return roleId;
} else { } else {
@ -62,9 +63,6 @@ public class AaiUserRoleServiceImpl implements AaiUserRoleService {
@Override @Override
public SimpleGrantedAuthority convertRepoIdToAuthority(String repoId) { public SimpleGrantedAuthority convertRepoIdToAuthority(String repoId) {
String role = convertRepoIdToEncodedAuthorityId(repoId); String role = convertRepoIdToEncodedAuthorityId(repoId);
if (role != null) {
role = URLEncoder.encode(role);
}
return new SimpleGrantedAuthority(role); return new SimpleGrantedAuthority(role);
} }

View File

@ -6,12 +6,15 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication; import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.context.SecurityContext; import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.oauth2.common.exceptions.UnauthorizedClientException;
import org.springframework.security.web.context.HttpSessionSecurityContextRepository; import org.springframework.security.web.context.HttpSessionSecurityContextRepository;
import org.springframework.session.ExpiringSession; import org.springframework.session.ExpiringSession;
import org.springframework.session.FindByIndexNameSessionRepository; import org.springframework.session.FindByIndexNameSessionRepository;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.util.Collection; import java.util.Collection;
import java.util.HashSet;
import java.util.Map; import java.util.Map;
@ -23,7 +26,7 @@ public class AuthoritiesUpdater extends HttpSessionSecurityContextRepository {
@Autowired @Autowired
FindByIndexNameSessionRepository sessions; FindByIndexNameSessionRepository sessions;
public void update(String id, Update update) { public void update(String id, Collection<? extends GrantedAuthority> authorities) {
if (sessions != null) { if (sessions != null) {
Map<String, ExpiringSession> map = sessions. Map<String, ExpiringSession> map = sessions.
findByIndexNameAndIndexValue(FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME, id); findByIndexNameAndIndexValue(FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME, id);
@ -35,7 +38,6 @@ public class AuthoritiesUpdater extends HttpSessionSecurityContextRepository {
Authentication authentication = securityContext.getAuthentication(); Authentication authentication = securityContext.getAuthentication();
if (authentication instanceof OIDCAuthenticationToken) { if (authentication instanceof OIDCAuthenticationToken) {
OIDCAuthenticationToken authOIDC = (OIDCAuthenticationToken) authentication; OIDCAuthenticationToken authOIDC = (OIDCAuthenticationToken) authentication;
Collection<? extends GrantedAuthority> authorities = update.authorities(authentication.getAuthorities());
logger.debug(authorities); logger.debug(authorities);
securityContext.setAuthentication(new OIDCAuthenticationToken(authOIDC.getSub(), authOIDC.getIssuer(), securityContext.setAuthentication(new OIDCAuthenticationToken(authOIDC.getSub(), authOIDC.getIssuer(),
authOIDC.getUserInfo(), authorities, authOIDC.getIdToken(), authOIDC.getUserInfo(), authorities, authOIDC.getIdToken(),
@ -49,6 +51,39 @@ public class AuthoritiesUpdater extends HttpSessionSecurityContextRepository {
} }
} }
public void update(String id, Update update) {
Collection<? extends GrantedAuthority> authorities = update.authorities(SecurityContextHolder.getContext().getAuthentication().getAuthorities());
this.update(id, authorities);
}
public void addRole(GrantedAuthority role) {
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
if (auth instanceof OIDCAuthenticationToken) {
OIDCAuthenticationToken oidcAuth = (OIDCAuthenticationToken) auth;
this.update(oidcAuth.getUserInfo().getEmail(), old -> {
HashSet<GrantedAuthority> authorities = new HashSet<>(old);
authorities.add(role);
return authorities;
});
} else {
throw new UnauthorizedClientException("User auth is not instance of OIDCAuthenticationToken");
}
}
public void removeRole(GrantedAuthority role) {
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
if (auth instanceof OIDCAuthenticationToken) {
OIDCAuthenticationToken oidcAuth = (OIDCAuthenticationToken) auth;
this.update(oidcAuth.getUserInfo().getEmail(), old -> {
HashSet<GrantedAuthority> authorities = new HashSet<>(old);
authorities.remove(role);
return authorities;
});
} else {
throw new UnauthorizedClientException("User auth is not instance of OIDCAuthenticationToken");
}
}
public interface Update { public interface Update {
Collection<? extends GrantedAuthority> authorities(Collection<? extends GrantedAuthority> old); Collection<? extends GrantedAuthority> authorities(Collection<? extends GrantedAuthority> old);
} }

View File

@ -5,7 +5,7 @@
xmlns:context="http://www.springframework.org/schema/context" xmlns:context="http://www.springframework.org/schema/context"
xmlns:security="http://www.springframework.org/schema/security" xmlns:security="http://www.springframework.org/schema/security"
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-4.2.xsd http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.2.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd" http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd"
> >