From e603487103a8814b65e3faf492d22efcf4359fe1 Mon Sep 17 00:00:00 2001 From: Antonis Lempesis Date: Wed, 21 Jul 2021 11:51:18 +0000 Subject: [PATCH] merged branch aai_roles_new to trunk --- pom.xml | 1 + .../config/AaiSecurityConfiguration.java | 61 +- ...ndLinkURIAuthenticationSuccessHandler.java | 62 +- .../config/OpenAIREAuthoritiesMapper.java | 48 ++ .../OpenAireProviderAuthoritiesMapper.java | 42 -- .../manager/controllers/BrokerController.java | 16 +- .../controllers/DashboardController.java | 8 +- .../controllers/MonitorController.java | 4 +- .../manager/controllers/PiWikController.java | 17 +- .../controllers/RepositoryController.java | 161 +++-- .../controllers/SushiliteController.java | 2 +- .../manager/controllers/UserController.java | 2 +- .../controllers/UserRoleController.java | 110 ++++ .../controllers/ValidatorController.java | 6 +- .../manager/domain/RepositorySnippet.java | 4 +- .../dnetlib/repo/manager/domain/dto/Role.java | 32 + .../dnetlib/repo/manager/domain/dto/User.java | 61 ++ .../exception/ResourceNotFoundException.java | 4 + .../manager/service/BrokerServiceImpl.java | 84 +-- .../manager/service/DashboardServiceImpl.java | 89 ++- .../repo/manager/service/EmailUtilsImpl.java | 79 +-- .../manager/service/PiWikServiceImpl.java | 8 +- .../manager/service/RepositoryService.java | 31 +- .../service/RepositoryServiceImpl.java | 595 +++++++++++------- .../manager/service/SushiliteServiceImpl.java | 2 +- .../manager/service/ValidatorServiceImpl.java | 6 +- .../aai/registry/AaiRegistryService.java | 285 +++++++++ .../service/aai/registry/RegistryCalls.java | 439 +++++++++++++ .../aai/registry/utils/RegistryUtils.java | 76 +++ .../security/AaiRoleMappingService.java | 120 ++++ .../service/security/AuthoritiesMapper.java | 73 +++ .../service/security/AuthoritiesUpdater.java | 98 +++ .../security/AuthorizationService.java | 69 ++ .../security/AuthorizationServiceImpl.java | 149 +++++ .../service/security/RoleMappingService.java | 74 +++ .../dnetlib/repo/manager/utils/Converter.java | 202 +++--- .../utils/DatasourceManagerClient.java | 5 + .../dnetlib/repo/manager/utils/HttpUtils.java | 99 +++ .../dnetlib/repo/manager/utils/JsonUtils.java | 40 ++ 39 files changed, 2588 insertions(+), 676 deletions(-) create mode 100644 src/main/java/eu/dnetlib/repo/manager/config/OpenAIREAuthoritiesMapper.java delete mode 100644 src/main/java/eu/dnetlib/repo/manager/config/OpenAireProviderAuthoritiesMapper.java create mode 100644 src/main/java/eu/dnetlib/repo/manager/controllers/UserRoleController.java create mode 100644 src/main/java/eu/dnetlib/repo/manager/domain/dto/Role.java create mode 100644 src/main/java/eu/dnetlib/repo/manager/domain/dto/User.java create mode 100644 src/main/java/eu/dnetlib/repo/manager/service/aai/registry/AaiRegistryService.java create mode 100644 src/main/java/eu/dnetlib/repo/manager/service/aai/registry/RegistryCalls.java create mode 100644 src/main/java/eu/dnetlib/repo/manager/service/aai/registry/utils/RegistryUtils.java create mode 100644 src/main/java/eu/dnetlib/repo/manager/service/security/AaiRoleMappingService.java create mode 100644 src/main/java/eu/dnetlib/repo/manager/service/security/AuthoritiesMapper.java create mode 100644 src/main/java/eu/dnetlib/repo/manager/service/security/AuthoritiesUpdater.java create mode 100644 src/main/java/eu/dnetlib/repo/manager/service/security/AuthorizationService.java create mode 100644 src/main/java/eu/dnetlib/repo/manager/service/security/AuthorizationServiceImpl.java create mode 100644 src/main/java/eu/dnetlib/repo/manager/service/security/RoleMappingService.java create mode 100644 src/main/java/eu/dnetlib/repo/manager/utils/DatasourceManagerClient.java create mode 100644 src/main/java/eu/dnetlib/repo/manager/utils/HttpUtils.java create mode 100644 src/main/java/eu/dnetlib/repo/manager/utils/JsonUtils.java diff --git a/pom.xml b/pom.xml index 6ac1652..6818795 100644 --- a/pom.xml +++ b/pom.xml @@ -312,6 +312,7 @@ + org.apache.maven.plugins maven-war-plugin 2.6 diff --git a/src/main/java/eu/dnetlib/repo/manager/config/AaiSecurityConfiguration.java b/src/main/java/eu/dnetlib/repo/manager/config/AaiSecurityConfiguration.java index 5c22184..67e5982 100644 --- a/src/main/java/eu/dnetlib/repo/manager/config/AaiSecurityConfiguration.java +++ b/src/main/java/eu/dnetlib/repo/manager/config/AaiSecurityConfiguration.java @@ -42,11 +42,6 @@ public class AaiSecurityConfiguration extends WebSecurityConfigurerAdapter { @Value("${webapp.dev.front}") private String webAppFrontEnd; - private Map userRoles = new HashMap(){{ - put("urn:geant:openaire.eu:group:Super+Administrator#aai.openaire.eu", "ROLE_ADMIN"); - put("urn:geant:openaire.eu:group:Content+Provider+Dashboard+Administrator#aai.openaire.eu","ROLE_PROVIDE_ADMIN"); - }}; - @Bean @Override public AuthenticationManager authenticationManagerBean() throws Exception { @@ -54,12 +49,12 @@ public class AaiSecurityConfiguration extends WebSecurityConfigurerAdapter { } @Override - protected void configure(AuthenticationManagerBuilder auth) throws Exception { + protected void configure(AuthenticationManagerBuilder auth) { auth.authenticationProvider(openIdConnectAuthenticationProvider()); } @Override - public void configure(WebSecurity web) throws Exception { + public void configure(WebSecurity web) { web.ignoring().antMatchers("/stats/**"); } @@ -70,33 +65,33 @@ public class AaiSecurityConfiguration extends WebSecurityConfigurerAdapter { .authorizeRequests() .anyRequest().authenticated() .and() - .httpBasic() - .authenticationEntryPoint(authenticationEntryPoint()) + .httpBasic() + .authenticationEntryPoint(authenticationEntryPoint()) .and() - .logout().logoutUrl("/openid_logout") - .invalidateHttpSession(true) - .deleteCookies("openAIRESession") - .logoutSuccessUrl(logoutSuccessUrl) + .logout().logoutUrl("/openid_logout") + .invalidateHttpSession(true) + .deleteCookies("openAIRESession") + .logoutSuccessUrl(logoutSuccessUrl) .and() - .addFilterBefore(openIdConnectAuthenticationFilter(), AbstractPreAuthenticatedProcessingFilter.class) + .addFilterBefore(openIdConnectAuthenticationFilter(), AbstractPreAuthenticatedProcessingFilter.class) ; } @Bean - public OIDCAuthenticationProvider openIdConnectAuthenticationProvider(){ + public OIDCAuthenticationProvider openIdConnectAuthenticationProvider() { OIDCAuthenticationProvider oidcProvider = new OIDCAuthenticationProvider(); oidcProvider.setAuthoritiesMapper(authoritiesMapper()); return oidcProvider; } @Bean - public OpenAireProviderAuthoritiesMapper authoritiesMapper(){ - OpenAireProviderAuthoritiesMapper authoritiesMapper = new OpenAireProviderAuthoritiesMapper(userRoles); + public OpenAIREAuthoritiesMapper authoritiesMapper() { + OpenAIREAuthoritiesMapper authoritiesMapper = new OpenAIREAuthoritiesMapper(); return authoritiesMapper; } @Bean - public StaticServerConfigurationService staticServerConfigurationService(){ + public StaticServerConfigurationService staticServerConfigurationService() { StaticServerConfigurationService staticServerConfigurationService = new StaticServerConfigurationService(); Map servers = new HashMap<>(); servers.put(oidcIssuer, serverConfiguration()); @@ -105,49 +100,49 @@ public class AaiSecurityConfiguration extends WebSecurityConfigurerAdapter { } @Bean - public StaticClientConfigurationService staticClientConfigurationService(){ + public StaticClientConfigurationService staticClientConfigurationService() { StaticClientConfigurationService staticClientConfigurationService = new StaticClientConfigurationService(); Map clients = new HashMap<>(); - clients.put(oidcIssuer,registeredClient()); + clients.put(oidcIssuer, registeredClient()); staticClientConfigurationService.setClients(clients); return staticClientConfigurationService; } @Bean - public RegisteredClient registeredClient(){ + public RegisteredClient registeredClient() { RegisteredClient registeredClient = new RegisteredClient(); registeredClient.setClientId(oidcId); registeredClient.setClientSecret(oidcSecret); - registeredClient.setScope(new HashSet<>(Arrays.asList("openid","eduperson_entitlement","profile", "email"))); + registeredClient.setScope(new HashSet<>(Arrays.asList("openid", "eduperson_entitlement", "profile", "email"))); registeredClient.setTokenEndpointAuthMethod(AuthMethod.SECRET_BASIC); registeredClient.setRedirectUris(new HashSet<>(Collections.singletonList(oidcDevHome))); return registeredClient; } @Bean - public StaticAuthRequestOptionsService staticAuthRequestOptionsService(){ + public StaticAuthRequestOptionsService staticAuthRequestOptionsService() { return new StaticAuthRequestOptionsService(); } @Bean - public PlainAuthRequestUrlBuilder plainAuthRequestUrlBuilder(){ + public PlainAuthRequestUrlBuilder plainAuthRequestUrlBuilder() { return new PlainAuthRequestUrlBuilder(); } @Bean - public ServerConfiguration serverConfiguration(){ + public ServerConfiguration serverConfiguration() { ServerConfiguration serverConfiguration = new ServerConfiguration(); serverConfiguration.setIssuer(oidcIssuer); - serverConfiguration.setAuthorizationEndpointUri(oidcIssuer+"authorize"); - serverConfiguration.setTokenEndpointUri(oidcIssuer+"token"); - serverConfiguration.setUserInfoUri(oidcIssuer+"userinfo"); - serverConfiguration.setJwksUri(oidcIssuer+"jwk"); - serverConfiguration.setRevocationEndpointUri(oidcIssuer+"revoke"); + serverConfiguration.setAuthorizationEndpointUri(oidcIssuer + "authorize"); + serverConfiguration.setTokenEndpointUri(oidcIssuer + "token"); + serverConfiguration.setUserInfoUri(oidcIssuer + "userinfo"); + serverConfiguration.setJwksUri(oidcIssuer + "jwk"); + serverConfiguration.setRevocationEndpointUri(oidcIssuer + "revoke"); return serverConfiguration; } @Bean - public LoginUrlAuthenticationEntryPoint authenticationEntryPoint(){ + public LoginUrlAuthenticationEntryPoint authenticationEntryPoint() { return new LoginUrlAuthenticationEntryPoint("/openid_connect_login"); } @@ -166,14 +161,14 @@ public class AaiSecurityConfiguration extends WebSecurityConfigurerAdapter { } @Bean - public StaticSingleIssuerService staticSingleIssuerService(){ + public StaticSingleIssuerService staticSingleIssuerService() { StaticSingleIssuerService staticSingleIssuerService = new StaticSingleIssuerService(); staticSingleIssuerService.setIssuer(oidcIssuer); return staticSingleIssuerService; } @Bean(initMethod = "init") - public FrontEndLinkURIAuthenticationSuccessHandler frontEndRedirect(){ + public FrontEndLinkURIAuthenticationSuccessHandler frontEndRedirect() { FrontEndLinkURIAuthenticationSuccessHandler frontEnd = new FrontEndLinkURIAuthenticationSuccessHandler(); frontEnd.setFrontEndURI(webAppFrontEnd); return frontEnd; diff --git a/src/main/java/eu/dnetlib/repo/manager/config/FrontEndLinkURIAuthenticationSuccessHandler.java b/src/main/java/eu/dnetlib/repo/manager/config/FrontEndLinkURIAuthenticationSuccessHandler.java index 27637a4..fc1ec49 100644 --- a/src/main/java/eu/dnetlib/repo/manager/config/FrontEndLinkURIAuthenticationSuccessHandler.java +++ b/src/main/java/eu/dnetlib/repo/manager/config/FrontEndLinkURIAuthenticationSuccessHandler.java @@ -1,19 +1,22 @@ package eu.dnetlib.repo.manager.config; -import com.google.gson.Gson; -import com.google.gson.JsonObject; +import com.google.gson.JsonParser; import org.apache.log4j.Logger; import org.mitre.openid.connect.model.OIDCAuthenticationToken; import org.springframework.beans.factory.annotation.Value; import org.springframework.security.core.Authentication; import org.springframework.security.web.authentication.AuthenticationSuccessHandler; +import org.springframework.session.FindByIndexNameSessionRepository; import javax.servlet.ServletException; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; -import java.net.URLEncoder; +import java.util.Base64; +import java.util.Date; +import java.util.regex.Matcher; +import java.util.regex.Pattern; public class FrontEndLinkURIAuthenticationSuccessHandler implements AuthenticationSuccessHandler { @@ -22,7 +25,7 @@ public class FrontEndLinkURIAuthenticationSuccessHandler implements Authenticati private static final Logger LOGGER = Logger .getLogger(FrontEndLinkURIAuthenticationSuccessHandler.class); - public void init(){ + public void init() { LOGGER.debug("Front end uri : " + frontEndURI); } @@ -32,53 +35,22 @@ public class FrontEndLinkURIAuthenticationSuccessHandler implements Authenticati @Override public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException { - OIDCAuthenticationToken authOIDC = (OIDCAuthenticationToken) authentication; - JsonObject userInfo = new JsonObject(); - - if (authOIDC.getUserInfo().getSub() == null) - userInfo.addProperty("sub", ""); - else - userInfo.addProperty("sub", URLEncoder.encode(authOIDC.getUserInfo().getSub(), "UTF-8")); - - - if(authOIDC.getUserInfo().getName() != null) - userInfo.addProperty("fullname", URLEncoder.encode(authOIDC.getUserInfo().getName(), "UTF-8")); - - if (authOIDC.getUserInfo().getGivenName() == null) - userInfo.addProperty("firstname", ""); - else - userInfo.addProperty("firstname", URLEncoder.encode(authOIDC.getUserInfo().getGivenName(), "UTF-8") + ""); - - if (authOIDC.getUserInfo().getFamilyName() == null) - userInfo.addProperty("lastname", ""); - else - userInfo.addProperty("lastname", URLEncoder.encode(authOIDC.getUserInfo().getFamilyName(), "UTF-8") + ""); - - userInfo.addProperty("email", authOIDC.getUserInfo().getEmail() + ""); - if (authOIDC.getUserInfo().getSource().getAsJsonArray("edu_person_entitlements") == null) - userInfo.addProperty("role", ""); - else - userInfo.addProperty("role", URLEncoder.encode(authOIDC.getUserInfo() - .getSource().getAsJsonArray("edu_person_entitlements").toString(), "UTF-8") + ""); - - - Cookie openAIREUser = new Cookie("openAIREUser", new Gson().toJson(userInfo) ); - openAIREUser.setMaxAge(14400); - openAIREUser.setPath("/"); - if(aai_mode.equalsIgnoreCase("production") || aai_mode.equalsIgnoreCase("beta")) - openAIREUser .setDomain(".openaire.eu"); -// openAIREUser.setDomain(".athenarc.gr"); - response.addCookie(openAIREUser); - + request.getSession().setAttribute(FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME, authOIDC.getUserInfo().getEmail()); Cookie accessToken = new Cookie("AccessToken", authOIDC.getAccessTokenValue()); - accessToken.setMaxAge(14400); - if(aai_mode.equalsIgnoreCase("production") || aai_mode.equalsIgnoreCase("beta")) + String regex = "^([A-Za-z0-9-_=]+)\\.([A-Za-z0-9-_=]+)\\.?([A-Za-z0-9-_.+=]*)$"; + Matcher matcher = Pattern.compile(regex).matcher(authOIDC.getAccessTokenValue()); + if (matcher.find()) { + long exp = new JsonParser().parse(new String(Base64.getDecoder().decode(matcher.group(2)))).getAsJsonObject().get("exp").getAsLong(); + accessToken.setMaxAge((int) (exp - (new Date().getTime() / 1000))); + } else { + accessToken.setMaxAge(3600); + } + if (aai_mode.equalsIgnoreCase("production") || aai_mode.equalsIgnoreCase("beta")) accessToken.setDomain(".openaire.eu"); accessToken.setPath("/"); -// accessToken.setDomain(".athenarc.gr"); response.addCookie(accessToken); response.sendRedirect(frontEndURI); } diff --git a/src/main/java/eu/dnetlib/repo/manager/config/OpenAIREAuthoritiesMapper.java b/src/main/java/eu/dnetlib/repo/manager/config/OpenAIREAuthoritiesMapper.java new file mode 100644 index 0000000..91bd1ce --- /dev/null +++ b/src/main/java/eu/dnetlib/repo/manager/config/OpenAIREAuthoritiesMapper.java @@ -0,0 +1,48 @@ +package eu.dnetlib.repo.manager.config; + +import com.google.gson.JsonArray; +import com.nimbusds.jwt.JWT; +import eu.dnetlib.repo.manager.service.security.AuthoritiesMapper; +import org.apache.log4j.Logger; +import org.mitre.openid.connect.client.OIDCAuthoritiesMapper; +import org.mitre.openid.connect.model.UserInfo; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.stereotype.Component; + +import java.util.*; + +@ComponentScan +@Component +public class OpenAIREAuthoritiesMapper implements OIDCAuthoritiesMapper { + + private static final Logger logger = Logger.getLogger(OpenAIREAuthoritiesMapper.class); + + @Value("${services.repo-manager.adminEmail}") + String adminEmail; + + @Override + public Collection mapAuthorities(JWT jwtToken, UserInfo userInfo) { + JsonArray entitlements = null; + Set authorities = new HashSet<>(); + if (userInfo != null && userInfo.getSource() != null) { + if (userInfo.getSource().getAsJsonArray("edu_person_entitlements") != null) { + entitlements = userInfo.getSource().getAsJsonArray("edu_person_entitlements"); + } else if (userInfo.getSource().getAsJsonArray("eduperson_entitlement") != null) { + entitlements = userInfo.getSource().getAsJsonArray("eduperson_entitlement"); + } + logger.debug("user info: " + userInfo + "\nentitlements: " + entitlements); + + // FIXME: delete this if statement when super administrators are set + if (userInfo.getEmail() != null && userInfo.getEmail().equals(adminEmail)) { + authorities.add(new SimpleGrantedAuthority("SUPER_ADMINISTRATOR")); + } + + authorities.addAll(AuthoritiesMapper.map(entitlements)); + } + return authorities; + } +} + diff --git a/src/main/java/eu/dnetlib/repo/manager/config/OpenAireProviderAuthoritiesMapper.java b/src/main/java/eu/dnetlib/repo/manager/config/OpenAireProviderAuthoritiesMapper.java deleted file mode 100644 index 16c98cf..0000000 --- a/src/main/java/eu/dnetlib/repo/manager/config/OpenAireProviderAuthoritiesMapper.java +++ /dev/null @@ -1,42 +0,0 @@ -package eu.dnetlib.repo.manager.config; - -import com.nimbusds.jwt.JWT; -import org.mitre.openid.connect.client.OIDCAuthoritiesMapper; -import org.mitre.openid.connect.model.UserInfo; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.security.core.GrantedAuthority; -import org.springframework.security.core.authority.SimpleGrantedAuthority; - -import java.util.*; - -public class OpenAireProviderAuthoritiesMapper implements OIDCAuthoritiesMapper { - - private static Logger logger = LoggerFactory.getLogger(OpenAireProviderAuthoritiesMapper.class); - - final private static String ROLE_CLAIMS = "edu_person_entitlements"; - - private Map userRolesMap; - - OpenAireProviderAuthoritiesMapper(Map userRoles) { - userRolesMap = new HashMap<>(); - userRoles.forEach((openaireRole, appRole) -> userRolesMap.put(openaireRole, new SimpleGrantedAuthority(appRole))); - } - - @Override - public Collection mapAuthorities(JWT idToken, UserInfo userInfo) { - Set out = new HashSet<>(); - out.add(new SimpleGrantedAuthority("ROLE_USER")); - - if(userInfo.getSource().getAsJsonArray(ROLE_CLAIMS) != null) { - userInfo.getSource().getAsJsonArray(ROLE_CLAIMS).forEach(role -> { - SimpleGrantedAuthority authority = userRolesMap.get(role.getAsString()); - if (authority != null) { - logger.debug("Role mapped " + role); - out.add(authority); - } - }); - } - return out; - } -} diff --git a/src/main/java/eu/dnetlib/repo/manager/controllers/BrokerController.java b/src/main/java/eu/dnetlib/repo/manager/controllers/BrokerController.java index b22b284..fa68b66 100644 --- a/src/main/java/eu/dnetlib/repo/manager/controllers/BrokerController.java +++ b/src/main/java/eu/dnetlib/repo/manager/controllers/BrokerController.java @@ -30,7 +30,7 @@ public class BrokerController{ @RequestMapping(value = "/getDatasourcesOfUser" , method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE) @ResponseBody - @PreAuthorize("hasRole('ROLE_USER')") + @PreAuthorize("hasAuthority('REGISTERED_USER')") public DatasourcesBroker getDatasourcesOfUser( @RequestParam("includeShared") @ApiParam(value = "Include shared datasources", required = true , defaultValue = "false") String includeShared, @@ -51,7 +51,7 @@ public class BrokerController{ method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE) @ResponseBody - @PreAuthorize("hasRole('ROLE_USER')") + @PreAuthorize("hasAuthority('REGISTERED_USER')") public EventsPage advancedShowEvents(@PathVariable("page") String page, @PathVariable("size") String size, @RequestBody AdvQueryObject advQueryObject) throws BrokerException, JSONException ,IOException{ @@ -62,7 +62,7 @@ public class BrokerController{ method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE) @ResponseBody - @PreAuthorize("hasRole('ROLE_USER')") + @PreAuthorize("hasAuthority('REGISTERED_USER')") public EventsPage showEvents(@RequestParam("datasourceName") String datasourceName, @RequestParam("topic") String topic, @RequestParam("page") String page, @@ -74,7 +74,7 @@ public class BrokerController{ method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE) @ResponseBody - @PreAuthorize("hasRole('ROLE_USER')") + @PreAuthorize("hasAuthority('REGISTERED_USER')") public Map> getSimpleSubscriptionsOfUser() throws BrokerException{ return brokerService.getSimpleSubscriptionsOfUser(((OIDCAuthenticationToken) SecurityContextHolder.getContext().getAuthentication()).getUserInfo().getEmail()); } @@ -83,7 +83,7 @@ public class BrokerController{ consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) @ResponseBody - @PreAuthorize("hasRole('ROLE_USER') ") + @PreAuthorize("hasAuthority('REGISTERED_USER') ") public Subscription subscribe(@RequestBody OpenaireSubscription obj) throws BrokerException{ return brokerService.subscribe(obj); } @@ -92,7 +92,7 @@ public class BrokerController{ consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) @ResponseBody - @PreAuthorize("hasRole('ROLE_USER')") + @PreAuthorize("hasAuthority('REGISTERED_USER')") public ResponseEntity unsubscribe(@PathVariable("subscriptionId") String subscriptionId) throws BrokerException{ return brokerService.unsubscribe(subscriptionId); } @@ -100,7 +100,7 @@ public class BrokerController{ @RequestMapping(value = "/getSubscription/{subscriptionId}" , method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE) @ResponseBody - @PreAuthorize("hasRole('ROLE_USER')") + @PreAuthorize("hasAuthority('REGISTERED_USER')") public Subscription getSubscription(@PathVariable("subscriptionId") String subscriptionId) throws BrokerException{ return brokerService.getSubscription(subscriptionId); } @@ -116,7 +116,7 @@ public class BrokerController{ @RequestMapping(value = "/getNotificationsBySubscriptionId/{subscriptionId}/{page}/{size}" , method = RequestMethod.GET ,produces = MediaType.APPLICATION_JSON_VALUE) @ResponseBody - @PreAuthorize("hasRole('ROLE_USER')") + @PreAuthorize("hasAuthority('REGISTERED_USER')") public EventsPage getNotificationsBySubscriptionId(@PathVariable("subscriptionId") String subscriptionId, @PathVariable("page") String page, @PathVariable("size") String size) throws BrokerException{ diff --git a/src/main/java/eu/dnetlib/repo/manager/controllers/DashboardController.java b/src/main/java/eu/dnetlib/repo/manager/controllers/DashboardController.java index e981d4e..aefcfd9 100644 --- a/src/main/java/eu/dnetlib/repo/manager/controllers/DashboardController.java +++ b/src/main/java/eu/dnetlib/repo/manager/controllers/DashboardController.java @@ -36,7 +36,7 @@ public class DashboardController { @RequestMapping(value = "/getRepositoriesSummary/{page}/{size}" , method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE) @ResponseBody - @PreAuthorize("hasRole('ROLE_USER')") + @PreAuthorize("hasAuthority('REGISTERED_USER')") public List getRepositoriesSummaryInfo( @PathVariable("page") String page, @PathVariable("size") String size) throws JSONException { @@ -46,7 +46,7 @@ public class DashboardController { @RequestMapping(value = "/collectionMonitorSummary/{repoId}" , method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE) @ResponseBody - @PreAuthorize("hasRole('ROLE_USER')") + @PreAuthorize("hasAuthority('REGISTERED_USER')") public CollectionMonitorSummary getCollectionMonitorSummary( @PathVariable("repoId") String repoId, @RequestParam(name = "size", required = false, defaultValue = "20") int size) throws JSONException { @@ -72,7 +72,7 @@ public class DashboardController { @RequestMapping(value = "/usageSummary/{repoId}" , method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE) @ResponseBody - @PreAuthorize("hasRole('ROLE_USER')") + @PreAuthorize("hasAuthority('REGISTERED_USER')") public UsageSummary getUsageSummary( @PathVariable("repoId") String repoId ) throws RepositoryServiceException { @@ -82,7 +82,7 @@ public class DashboardController { @RequestMapping(value = "/brokerSummary/{ds_name}" , method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE) @ResponseBody - @PreAuthorize("hasRole('ROLE_USER')") + @PreAuthorize("hasAuthority('REGISTERED_USER')") public BrokerSummary getBrokerSummary( @PathVariable("ds_name") String datasourceName) throws BrokerException { return new BrokerSummary(brokerService.getSimpleSubscriptionsOfUser( ((OIDCAuthenticationToken) SecurityContextHolder.getContext().getAuthentication()).getUserInfo().getEmail()), brokerService.getTopicsForDatasource(datasourceName)); diff --git a/src/main/java/eu/dnetlib/repo/manager/controllers/MonitorController.java b/src/main/java/eu/dnetlib/repo/manager/controllers/MonitorController.java index e8fb20b..f1c7b2d 100644 --- a/src/main/java/eu/dnetlib/repo/manager/controllers/MonitorController.java +++ b/src/main/java/eu/dnetlib/repo/manager/controllers/MonitorController.java @@ -29,7 +29,7 @@ public class MonitorController { @RequestMapping(value = "/getJobsOfUser" , method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE) @ResponseBody - @PreAuthorize("hasRole('ROLE_USER')") + @PreAuthorize("hasAuthority('REGISTERED_USER')") public JobsOfUser getJobsOfUser(@RequestParam(value = "jobType", required = false) @ApiParam(value = "Equals to filter job type on validation history page") String jobType, @RequestParam("offset") @ApiParam(value = "Page number", required = true) String offset, @@ -43,7 +43,7 @@ public class MonitorController { @RequestMapping(value = "/getJobsOfUserPerValidationStatus" , method = RequestMethod.GET,produces = MediaType.APPLICATION_JSON_VALUE) @ResponseBody - @PreAuthorize("hasRole('ROLE_USER')") + @PreAuthorize("hasAuthority('REGISTERED_USER')") public int getJobsOfUserPerValidationStatus(@RequestBody String jobType, @RequestBody String validationStatus) throws JSONException { return monitorService.getJobsOfUserPerValidationStatus(((OIDCAuthenticationToken) SecurityContextHolder.getContext().getAuthentication()).getUserInfo().getEmail(), jobType, validationStatus); diff --git a/src/main/java/eu/dnetlib/repo/manager/controllers/PiWikController.java b/src/main/java/eu/dnetlib/repo/manager/controllers/PiWikController.java index d9c1b5e..70b7c37 100644 --- a/src/main/java/eu/dnetlib/repo/manager/controllers/PiWikController.java +++ b/src/main/java/eu/dnetlib/repo/manager/controllers/PiWikController.java @@ -6,7 +6,6 @@ import eu.dnetlib.repo.manager.domain.OrderByType; import eu.dnetlib.repo.manager.domain.Paging; import eu.dnetlib.repo.manager.domain.RepositoryServiceException; import eu.dnetlib.repo.manager.service.PiWikServiceImpl; -import eu.dnetlib.repo.manager.service.RepositoryService; import io.swagger.annotations.Api; import io.swagger.annotations.ApiImplicitParam; import io.swagger.annotations.ApiImplicitParams; @@ -40,19 +39,15 @@ public class PiWikController { @Autowired private PiWikServiceImpl piWikService; - @Autowired - private RepositoryService repositoryService; - - @RequestMapping(value = "/getPiwikSiteForRepo/{repositoryId}" , method = RequestMethod.GET,produces = MediaType.APPLICATION_JSON_VALUE) @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('SUPER_ADMINISTRATOR', 'CONTENT_PROVIDER_DASHBOARD_ADMINISTRATOR') or @authorizationService.isMemberOf(#repositoryId) or (@repositoryService.getRepositoryById(#repositoryId).registeredBy=='null' and hasAuthority('REGISTERED_USER'))") public PiwikInfo getPiwikSiteForRepo(@PathVariable("repositoryId") String repositoryId) { return piWikService.getPiwikSiteForRepo(repositoryId); } @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('SUPER_ADMINISTRATOR', 'CONTENT_PROVIDER_DASHBOARD_ADMINISTRATOR') or @authorizationService.isMemberOf(#piwikInfo.repositoryId) or (@repositoryService.getRepositoryById(#piwikInfo.repositoryId).registeredBy=='null' and hasAuthority('REGISTERED_USER'))") public PiwikInfo savePiwikInfo(@RequestBody PiwikInfo piwikInfo) { return piWikService.savePiwikInfo(piwikInfo); } @@ -154,14 +149,14 @@ public class PiWikController { @RequestMapping(value = "/approvePiwikSite/{repositoryId}" , method = RequestMethod.GET) @ResponseBody - @PreAuthorize("hasRole('ROLE_ADMIN') or hasRole('ROLE_PROVIDE_ADMIN')") + @PreAuthorize("hasAuthority('SUPER_ADMINISTRATOR') or hasAuthority('CONTENT_PROVIDER_DASHBOARD_ADMINISTRATOR')") public ResponseEntity approvePiwikSite(@PathVariable("repositoryId") String repositoryId) { return piWikService.approvePiwikSite(repositoryId); } @RequestMapping(value = "/getOpenaireId/{repositoryId}" , method = RequestMethod.GET,produces = MediaType.APPLICATION_JSON_VALUE) @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('SUPER_ADMINISTRATOR', 'CONTENT_PROVIDER_DASHBOARD_ADMINISTRATOR') or @authorizationService.isMemberOf(#repositoryId) or (@repositoryService.getRepositoryById(#repositoryId).registeredBy=='null' and hasAuthority('REGISTERED_USER'))") public String getOpenaireId(@PathVariable("repositoryId") String repositoryId){ return piWikService.getOpenaireId(repositoryId); } @@ -169,14 +164,14 @@ public class PiWikController { @RequestMapping(value = "/markPiwikSiteAsValidated/{repositoryId}" , method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE) @ResponseBody - @PreAuthorize("hasRole('ROLE_ADMIN') or hasRole('ROLE_PROVIDE_ADMIN')") + @PreAuthorize("hasAuthority('SUPER_ADMINISTRATOR') or hasAuthority('CONTENT_PROVIDER_DASHBOARD_ADMINISTRATOR')") public ResponseEntity markPiwikSiteAsValidated(@PathVariable("repositoryId") String repositoryId) throws RepositoryServiceException { return piWikService.markPiwikSiteAsValidated(repositoryId); } @RequestMapping(value = "/enableMetricsForRepository", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE) - @PreAuthorize("hasRole('ROLE_ADMIN') or hasRole('ROLE_PROVIDE_ADMIN') or (hasRole('ROLE_USER') and #piwikInfo.requestorEmail == authentication.userInfo.email)") + @PreAuthorize("hasAuthority('SUPER_ADMINISTRATOR') or hasAuthority('CONTENT_PROVIDER_DASHBOARD_ADMINISTRATOR') or (hasAuthority('REGISTERED_USER') and #piwikInfo.requestorEmail == authentication.userInfo.email)") public PiwikInfo enableMetricsForRepository(@RequestParam("officialName") String officialName, @RequestParam("repoWebsite") String repoWebsite, @RequestBody PiwikInfo piwikInfo) throws RepositoryServiceException { diff --git a/src/main/java/eu/dnetlib/repo/manager/controllers/RepositoryController.java b/src/main/java/eu/dnetlib/repo/manager/controllers/RepositoryController.java index 10cc8e2..c936335 100644 --- a/src/main/java/eu/dnetlib/repo/manager/controllers/RepositoryController.java +++ b/src/main/java/eu/dnetlib/repo/manager/controllers/RepositoryController.java @@ -3,35 +3,48 @@ package eu.dnetlib.repo.manager.controllers; import eu.dnetlib.domain.data.Repository; import eu.dnetlib.domain.data.RepositoryInterface; import eu.dnetlib.repo.manager.domain.*; +import eu.dnetlib.repo.manager.domain.dto.User; import eu.dnetlib.repo.manager.exception.ResourceNotFoundException; -import eu.dnetlib.repo.manager.service.RepositoryServiceImpl; +import eu.dnetlib.repo.manager.service.RepositoryService; +import eu.dnetlib.repo.manager.service.security.AuthorizationService; +import eu.dnetlib.repo.manager.utils.JsonUtils; import io.swagger.annotations.Api; import org.apache.log4j.Logger; import org.json.JSONException; import org.mitre.openid.connect.model.OIDCAuthenticationToken; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; import org.springframework.security.access.prepost.PostAuthorize; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.web.bind.annotation.*; +import javax.ws.rs.core.Response; import java.io.IOException; import java.util.List; import java.util.Map; @RestController -@RequestMapping(value = "/repository") -@Api(description = "Repository API", tags = {"repository"}) +@RequestMapping(value = "/repositories") +@Api(description = "Repository API", tags = {"repositories"}) public class RepositoryController { - private static Logger logger = Logger.getLogger(RepositoryController.class); + private static final Logger logger = Logger.getLogger(RepositoryController.class); + + private final RepositoryService repositoryService; + private final AuthorizationService authorizationService; @Autowired - private RepositoryServiceImpl repositoryService; + RepositoryController(RepositoryService repositoryService, + AuthorizationService authorizationService) { + this.repositoryService = repositoryService; + this.authorizationService = authorizationService; + } - @RequestMapping(value = "/getCountries", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE) + @RequestMapping(value = "/countries", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE) @ResponseBody public Country[] getCountries() { return repositoryService.getCountries(); @@ -42,28 +55,26 @@ public class RepositoryController { @ResponseBody public List getRepositoriesByCountry(@PathVariable("country") String country, @PathVariable("mode") String mode, - @RequestParam(value = "managed",required=false) Boolean managed) throws JSONException, IOException { + @RequestParam(value = "managed", required = false) Boolean managed) throws JSONException, IOException { return repositoryService.getRepositoriesByCountry(country, mode, managed); } - @RequestMapping(value = "/getRepositoriesOfUser/{page}/{size}",method = RequestMethod.GET, + @RequestMapping(value = "/snippets/user", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE) @ResponseBody - @PreAuthorize("hasRole('ROLE_USER')") - public List getRepositoriesOfUser( - @PathVariable("page") String page, - @PathVariable("size") String size) throws JSONException, IOException { - return repositoryService.getRepositoriesSnippetOfUser(((OIDCAuthenticationToken) SecurityContextHolder.getContext().getAuthentication()).getUserInfo().getEmail(), page, size); + @PreAuthorize("hasAuthority('REGISTERED_USER')") + public List getRepositoriesSnippetsOfUser() throws Exception { + return repositoryService.getRepositoriesSnippetsOfUser("0", "100"); } - @RequestMapping(value = "/searchRegisteredRepositories/{page}/{size}",method = RequestMethod.GET, + @RequestMapping(value = "/searchRegisteredRepositories/{page}/{size}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE) @ResponseBody - @PreAuthorize("hasRole('ROLE_ADMIN') or hasRole('ROLE_PROVIDE_ADMIN')") - public List searchRegisteredRepositories(@RequestParam(name="country", required=false) String country, - @RequestParam(name="typology", required=false) String typology, - @RequestParam(name="englishName", required=false) String englishName, - @RequestParam(name="officialName", required=false) String officialName, + @PreAuthorize("hasAuthority('SUPER_ADMINISTRATOR') or hasAuthority('CONTENT_PROVIDER_DASHBOARD_ADMINISTRATOR')") + public List searchRegisteredRepositories(@RequestParam(name = "country", required = false) String country, + @RequestParam(name = "typology", required = false) String typology, + @RequestParam(name = "englishName", required = false) String englishName, + @RequestParam(name = "officialName", required = false) String officialName, @RequestParam("requestSortBy") String requestSortBy, @RequestParam("order") String order, @PathVariable("page") int page, @@ -75,14 +86,14 @@ public class RepositoryController { @RequestMapping(value = "/getRepositoryById/{id}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE) @ResponseBody - @PostAuthorize("hasRole('ROLE_ADMIN') or hasRole('ROLE_PROVIDE_ADMIN') or ((returnObject.registeredBy=='null' or returnObject.registeredBy==authentication.userInfo.email) and hasRole('ROLE_USER'))") - public Repository getRepositoryById(@PathVariable("id") String id) throws JSONException,ResourceNotFoundException { + @PostAuthorize("hasAnyRole('SUPER_ADMINISTRATOR', 'CONTENT_PROVIDER_DASHBOARD_ADMINISTRATOR') or @authorizationService.isMemberOf(#id) or (returnObject.registeredBy=='null' and hasAuthority('REGISTERED_USER'))") + public Repository getRepositoryById(@PathVariable("id") String id) throws JSONException, ResourceNotFoundException { Repository repo = repositoryService.getRepositoryById(id); - if (repo != null) - logger.info("Returning repository " + repo.getId() + " registered by " + repo.getRegisteredBy()); - else - logger.info("Requested repository " + id + " not found"); + if (repo != null) + logger.info("Returning repository " + repo.getId() + " registered by " + repo.getRegisteredBy()); + else + logger.info("Requested repository " + id + " not found"); return repo; } @@ -90,7 +101,7 @@ public class RepositoryController { produces = MediaType.APPLICATION_JSON_VALUE) @ResponseBody public List getRepositoryAggregations(@PathVariable("id") String id) throws JSONException { - return repositoryService.getRepositoryAggregations(id,0,20); + return repositoryService.getRepositoryAggregations(id, 0, 20); } @RequestMapping(value = "/getRepositoryAggregationsByYear/{id}", method = RequestMethod.GET, @@ -112,7 +123,7 @@ public class RepositoryController { @RequestMapping(value = "/getRepositoryInterface/{id}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE) @ResponseBody - @PostAuthorize("hasRole('ROLE_ADMIN') or hasRole('ROLE_PROVIDE_ADMIN') or ((@repositoryService.getRepositoryById(#id).registeredBy==authentication.userInfo.email or @repositoryService.getRepositoryById(#id).registeredBy=='null' ) and hasRole('ROLE_USER'))") + @PostAuthorize("hasAuthority('SUPER_ADMINISTRATOR') or hasAuthority('CONTENT_PROVIDER_DASHBOARD_ADMINISTRATOR') or @authorizationService.isMemberOf(#id) or (@repositoryService.getRepositoryById(#id).registeredBy=='null' and hasAuthority('REGISTERED_USER'))") public List getRepositoryInterface(@PathVariable("id") String id) throws JSONException { return repositoryService.getRepositoryInterface(id); } @@ -120,7 +131,8 @@ public class RepositoryController { @RequestMapping(value = "/addRepository", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE) @ResponseBody - @PreAuthorize("hasRole('ROLE_ADMIN') or hasRole('ROLE_PROVIDE_ADMIN') or ((#repository.registeredBy==authentication.userInfo.email or returnObject.registeredBy=='null') and hasRole('ROLE_USER'))") +// @PreAuthorize("hasAuthority('SUPER_ADMINISTRATOR') or hasAuthority('CONTENT_PROVIDER_DASHBOARD_ADMINISTRATOR') or (hasAuthority(@authorizationService.convertRepoIdToRoleId(#repository.id)) or hasAuthority(@authorizationService.convertRepoIdToRoleId(returnObject.id)))") + @PreAuthorize("hasAuthority('SUPER_ADMINISTRATOR') or hasAuthority('CONTENT_PROVIDER_DASHBOARD_ADMINISTRATOR') or hasAuthority('REGISTERED_USER')") public Repository addRepository(@RequestParam("datatype") String datatype, @RequestBody Repository repository) throws Exception { @@ -130,105 +142,136 @@ public class RepositoryController { @RequestMapping(value = "/getDnetCountries", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE) @ResponseBody - public List getDnetCountries(){ + public List getDnetCountries() { return repositoryService.getDnetCountries(); } @RequestMapping(value = "/getTypologies", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE) @ResponseBody - public List getTypologies(){ + public List getTypologies() { return repositoryService.getTypologies(); } @RequestMapping(value = "/getTimezones", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE) @ResponseBody - public List getTimezones(){ + public List getTimezones() { return repositoryService.getTimezones(); } @RequestMapping(value = "/updateRepository", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE) @ResponseBody - @PreAuthorize("hasRole('ROLE_ADMIN') or hasRole('ROLE_PROVIDE_ADMIN') or ((#repository.registeredBy==authentication.userInfo.email or #repository.registeredBy=='null') and hasRole('ROLE_USER'))") - public Repository updateRepository(@RequestBody Repository repository,Authentication authentication) throws Exception { + @PreAuthorize("hasAuthority('SUPER_ADMINISTRATOR') or hasAuthority('CONTENT_PROVIDER_DASHBOARD_ADMINISTRATOR') or @authorizationService.isMemberOf(#repository.id)") + public Repository updateRepository(@RequestBody Repository repository, Authentication authentication) throws Exception { return repositoryService.updateRepository(repository, authentication); } @RequestMapping(value = "/deleteInterface/", method = RequestMethod.DELETE) - @PreAuthorize("hasRole('ROLE_USER') and #registeredBy == authentication.userInfo.email") - public void deleteRepositoryInterface(@RequestParam("id") String id , - @RequestParam("registeredBy") String registeredBy){ + @PreAuthorize("@authorizationService.isMemberOf(#id)") + public void deleteRepositoryInterface(@RequestParam("id") String id, + @RequestParam("registeredBy") String registeredBy) { repositoryService.deleteRepositoryInterface(id, registeredBy); } @RequestMapping(value = "/addInterface", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE) @ResponseBody - @PreAuthorize("hasRole('ROLE_ADMIN') or hasRole('ROLE_PROVIDE_ADMIN') or ((@repositoryService.getRepositoryById(#repoId).registeredBy==authentication.userInfo.email or @repositoryService.getRepositoryById(#repoId).registeredBy=='null') and hasRole('ROLE_USER'))") + @PreAuthorize("hasAuthority('SUPER_ADMINISTRATOR') or hasAuthority('CONTENT_PROVIDER_DASHBOARD_ADMINISTRATOR') or @authorizationService.isMemberOf(#id)") public RepositoryInterface addRepositoryInterface(@RequestParam("datatype") String datatype, - @RequestParam("repoId") String repoId, + @RequestParam("id") String id, @RequestParam("registeredBy") String registeredBy, @RequestParam(value = "comment", required = false) String comment, @RequestBody RepositoryInterface repositoryInterface) throws Exception { - return repositoryService.addRepositoryInterface(datatype, repoId, registeredBy, comment, repositoryInterface); + return repositoryService.addRepositoryInterface(datatype, id, registeredBy, comment, repositoryInterface); } - @RequestMapping(value = "/getUrlsOfUserRepos/{page}/{size}/",method = RequestMethod.GET, + @RequestMapping(value = "/getUrlsOfUserRepos/{page}/{size}/", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE) @ResponseBody - @PreAuthorize("hasRole('ROLE_USER')") - public List getUrlsOfUserRepos( - @PathVariable("page") String page, - @PathVariable("size") String size) throws JSONException { + @PreAuthorize("hasAuthority('REGISTERED_USER')") + public List getUrlsOfUserRepos(@PathVariable("page") String page, @PathVariable("size") String size) { return repositoryService.getUrlsOfUserRepos(((OIDCAuthenticationToken) SecurityContextHolder.getContext().getAuthentication()).getUserInfo().getEmail(), page, size); } - @RequestMapping(value = "/getDatasourceVocabularies/{mode}",method = RequestMethod.GET, + @RequestMapping(value = "/getDatasourceVocabularies/{mode}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE) @ResponseBody public List getDatasourceVocabularies(@PathVariable("mode") String mode) { - return repositoryService.getDatasourceVocabularies(mode); + return repositoryService.getDatasourceVocabularies(mode); } - @RequestMapping(value = "/getCompatibilityClasses/{mode}",method = RequestMethod.GET, + @RequestMapping(value = "/getCompatibilityClasses/{mode}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE) @ResponseBody - public Map getCompatibilityClasses(@PathVariable("mode") String mode) { + public Map getCompatibilityClasses(@PathVariable("mode") String mode) { return repositoryService.getCompatibilityClasses(mode); } - @RequestMapping(value = "/getDatasourceClasses/{mode}",method = RequestMethod.GET, + @RequestMapping(value = "/getDatasourceClasses/{mode}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE) @ResponseBody - public Map getDatasourceClasses(@PathVariable("mode") String mode) { - return repositoryService.getDatasourceClasses(mode); + public Map getDatasourceClasses(@PathVariable("mode") String mode) { + return repositoryService.getDatasourceClasses(mode); } - @RequestMapping(value = "/getMetricsInfoForRepository/{repoId}",method = RequestMethod.GET, + @RequestMapping(value = "/getMetricsInfoForRepository/{id}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE) @ResponseBody - public MetricsInfo getMetricsInfoForRepository(@PathVariable("repoId") String repoId) throws RepositoryServiceException { - return repositoryService.getMetricsInfoForRepository(repoId); + public MetricsInfo getMetricsInfoForRepository(@PathVariable("id") String id) throws RepositoryServiceException { + return repositoryService.getMetricsInfoForRepository(id); } - @RequestMapping(value = "/getListLatestUpdate/{mode}",method = RequestMethod.GET, + @RequestMapping(value = "/getListLatestUpdate/{mode}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE) @ResponseBody - public Map getListLatestUpdate(@PathVariable("mode") String mode) throws JSONException { + public Map getListLatestUpdate(@PathVariable("mode") String mode) throws JSONException { return repositoryService.getListLatestUpdate(mode); } @RequestMapping(value = "/updateRepositoryInterface", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE) @ResponseBody - @PreAuthorize("hasRole('ROLE_ADMIN') or hasRole('ROLE_PROVIDE_ADMIN') or ((@repositoryService.getRepositoryById(#repoId).registeredBy==authentication.userInfo.email or @repositoryService.getRepositoryById(#repoId).registeredBy=='null') and hasRole('ROLE_USER'))") - public RepositoryInterface updateRepositoryInterface(@RequestParam("repoId") String repoId, + @PreAuthorize("hasAuthority('SUPER_ADMINISTRATOR') or hasAuthority('CONTENT_PROVIDER_DASHBOARD_ADMINISTRATOR') or @authorizationService.isMemberOf(#id)") + public RepositoryInterface updateRepositoryInterface(@RequestParam("id") String id, @RequestParam("registeredBy") String registeredBy, @RequestParam(value = "comment", required = false) String comment, @RequestBody RepositoryInterface repositoryInterface) throws Exception { - return repositoryService.updateRepositoryInterface(repoId, registeredBy, comment, repositoryInterface); + return repositoryService.updateRepositoryInterface(id, registeredBy, comment, repositoryInterface); + } + + + /////////////////////////////////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////////////////////////////////////// + + /** + * Get all the admins of the repository + */ + @RequestMapping(method = RequestMethod.GET, path = "{id}/admins") + @PreAuthorize("hasAnyAuthority('SUPER_ADMINISTRATOR', 'CONTENT_PROVIDER_DASHBOARD_ADMINISTRATOR') or @authorizationService.isMemberOf(#id)") + public ResponseEntity> getAdminsOfARepo(@PathVariable("id") String id) { + return new ResponseEntity<>(authorizationService.getAdminsOfRepo(id), HttpStatus.OK); + } + + /** + * Subscribe to repo by email + */ + @RequestMapping(method = RequestMethod.POST, path = "{id}/admins") + @PreAuthorize("hasAnyAuthority('SUPER_ADMINISTRATOR', 'CONTENT_PROVIDER_DASHBOARD_ADMINISTRATOR') or @authorizationService.isMemberOf(#id)") + public Response subscribeByEmail(@PathVariable("id") String id, @RequestBody String email) throws ResourceNotFoundException { + authorizationService.addAdmin(id, email); + return Response.status(HttpStatus.OK.value()).entity(JsonUtils.createResponse("Role has been assigned").toString()).type(javax.ws.rs.core.MediaType.APPLICATION_JSON).build(); + } + + /** + * Unsubscribe from repo by email + */ + @RequestMapping(method = RequestMethod.DELETE, path = "{id}/admins/{email:.+}") + @PreAuthorize("hasAnyAuthority('SUPER_ADMINISTRATOR', 'CONTENT_PROVIDER_DASHBOARD_ADMINISTRATOR') or @authorizationService.isMemberOf(#id)") + public ResponseEntity unsubscribeByEmail(@PathVariable("id") String id, @PathVariable("email") String email) throws ResourceNotFoundException { + authorizationService.removeAdmin(id, email); + return new ResponseEntity<>(HttpStatus.NO_CONTENT); } } diff --git a/src/main/java/eu/dnetlib/repo/manager/controllers/SushiliteController.java b/src/main/java/eu/dnetlib/repo/manager/controllers/SushiliteController.java index 7f934d5..7d7aa4e 100644 --- a/src/main/java/eu/dnetlib/repo/manager/controllers/SushiliteController.java +++ b/src/main/java/eu/dnetlib/repo/manager/controllers/SushiliteController.java @@ -19,7 +19,7 @@ public class SushiliteController { @RequestMapping(value = "/getReportResults/{page}/{pageSize}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE) @ResponseBody - @PreAuthorize("hasRole('ROLE_USER')") + @PreAuthorize("hasAuthority('REGISTERED_USER')") public ReportResponseWrapper getReportResults(@PathVariable("page") String page, @PathVariable("pageSize") String pageSize, @RequestParam(value = "Report") String Report, diff --git a/src/main/java/eu/dnetlib/repo/manager/controllers/UserController.java b/src/main/java/eu/dnetlib/repo/manager/controllers/UserController.java index a7641a2..08e2119 100644 --- a/src/main/java/eu/dnetlib/repo/manager/controllers/UserController.java +++ b/src/main/java/eu/dnetlib/repo/manager/controllers/UserController.java @@ -18,7 +18,7 @@ public class UserController { private UserServiceImpl userService; @RequestMapping(value = "/login" , method = RequestMethod.GET) - @PreAuthorize("hasRole('ROLE_USER')") + @PreAuthorize("hasAuthority('REGISTERED_USER')") public ResponseEntity login() { return userService.login(); } diff --git a/src/main/java/eu/dnetlib/repo/manager/controllers/UserRoleController.java b/src/main/java/eu/dnetlib/repo/manager/controllers/UserRoleController.java new file mode 100644 index 0000000..dfed035 --- /dev/null +++ b/src/main/java/eu/dnetlib/repo/manager/controllers/UserRoleController.java @@ -0,0 +1,110 @@ +package eu.dnetlib.repo.manager.controllers; + +import eu.dnetlib.repo.manager.domain.dto.Role; +import eu.dnetlib.repo.manager.service.aai.registry.AaiRegistryService; +import eu.dnetlib.repo.manager.service.security.AuthoritiesUpdater; +import eu.dnetlib.repo.manager.service.security.AuthorizationService; +import eu.dnetlib.repo.manager.service.security.RoleMappingService; +import eu.dnetlib.repo.manager.utils.JsonUtils; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.*; + +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import java.util.Collection; + +@RestController +@RequestMapping(value = "/role-management") +@Api(description = "Role Management", value = "role-management") +public class UserRoleController { + + private final AaiRegistryService aaiRegistryService; + private final AuthoritiesUpdater authoritiesUpdater; + private final RoleMappingService roleMappingService; + private final AuthorizationService authorizationService; + + @Autowired + UserRoleController(AaiRegistryService aaiRegistryService, + AuthoritiesUpdater authoritiesUpdater, + RoleMappingService roleMappingService, + AuthorizationService authorizationService) { + this.aaiRegistryService = aaiRegistryService; + this.authoritiesUpdater = authoritiesUpdater; + this.roleMappingService = roleMappingService; + this.authorizationService = authorizationService; + } + + /** + * Get the role with the given id. + **/ + @RequestMapping(method = RequestMethod.GET, path = "/role/{id}") +// @PreAuthorize("hasAnyAuthority('REGISTERED_USER', 'SUPER_ADMINISTRATOR', 'CONTENT_PROVIDER_DASHBOARD_ADMINISTRATOR')") + public Response getRole(@RequestParam(value = "type", defaultValue = "datasource") String type, @PathVariable("id") String 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(); + } + + /** + * Create a new role with the given name and description. + **/ + @RequestMapping(method = RequestMethod.POST, path = "/role") + @PreAuthorize("hasAnyAuthority('SUPER_ADMINISTRATOR')") + public Response createRole(@RequestBody Role role) { + aaiRegistryService.createRole(role); + return Response.status(HttpStatus.OK.value()).entity(JsonUtils.createResponse("Role has been created").toString()).type(MediaType.APPLICATION_JSON).build(); + } + + /** + * Subscribe to a type(Community, etc.) with id(ee, egi, etc.) + */ + @ApiOperation(value = "subscribe") + @RequestMapping(method = RequestMethod.POST, path = "/subscribe/{type}/{id}") + @PreAuthorize("hasAnyAuthority('SUPER_ADMINISTRATOR', 'CONTENT_PROVIDER_DASHBOARD_ADMINISTRATOR')") + public Response subscribe(@PathVariable("type") String type, @PathVariable("id") String id) { + Integer coPersonId = aaiRegistryService.getCoPersonIdByIdentifier(); + if (coPersonId == null) { + coPersonId = aaiRegistryService.getCoPersonIdByEmail(); + } + Integer couId = aaiRegistryService.getCouId(type, id); + if (couId != null) { + Integer role = aaiRegistryService.getRoleId(coPersonId, couId); + aaiRegistryService.assignMemberRole(coPersonId, couId, role); + + // Add role to current authorities + authoritiesUpdater.addRole(roleMappingService.convertRepoIdToAuthority(id)); + + return Response.status(HttpStatus.OK.value()).entity(JsonUtils.createResponse("Role has been assigned").toString()).type(MediaType.APPLICATION_JSON).build(); + } else { + return Response.status(HttpStatus.NOT_FOUND.value()).entity(JsonUtils.createResponse("Role has not been found").toString()).type(MediaType.APPLICATION_JSON).build(); + } + } + ///////////////////////////////////////////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////////////////////////////////////////// + + @RequestMapping(method = RequestMethod.GET, path = "/users/couid/{id}") + @PreAuthorize("hasAnyAuthority('SUPER_ADMINISTRATOR', 'CONTENT_PROVIDER_DASHBOARD_ADMINISTRATOR')") + public ResponseEntity getUsersByCouId(@PathVariable("id") Integer id) { +// calls.getUserByCoId() + return ResponseEntity.ok(aaiRegistryService.getUsersByCouId(id).toString()); + } + + + @RequestMapping(method = RequestMethod.GET, path = "/users/{email}/roles") + @PreAuthorize("hasAnyAuthority('SUPER_ADMINISTRATOR', 'CONTENT_PROVIDER_DASHBOARD_ADMINISTRATOR') or hasAuthority('REGISTERED_USER') and authentication.userInfo.email==#email") + public ResponseEntity> getRolesByEmail(@PathVariable("email") String email) { + return ResponseEntity.ok(authorizationService.getUserRoles(email)); + } + + + @RequestMapping(method = RequestMethod.GET, path = "/user/roles/my") + @PreAuthorize("hasAuthority('REGISTERED_USER')") + public ResponseEntity> getRoleNames() { + return ResponseEntity.ok(authorizationService.getUserRoles()); + } + +} \ No newline at end of file diff --git a/src/main/java/eu/dnetlib/repo/manager/controllers/ValidatorController.java b/src/main/java/eu/dnetlib/repo/manager/controllers/ValidatorController.java index 1811103..faf4c38 100644 --- a/src/main/java/eu/dnetlib/repo/manager/controllers/ValidatorController.java +++ b/src/main/java/eu/dnetlib/repo/manager/controllers/ValidatorController.java @@ -38,7 +38,7 @@ public class ValidatorController { consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) @ResponseBody - @PreAuthorize("hasRole('ROLE_USER') and #jobForValidation.userEmail == authentication.userInfo.email") + @PreAuthorize("hasAuthority('REGISTERED_USER') and #jobForValidation.userEmail == authentication.userInfo.email") public JobForValidation submitJobForValidation(@RequestBody JobForValidation jobForValidation) throws ValidatorServiceException { return validatorService.submitJobForValidation(jobForValidation); } @@ -47,7 +47,7 @@ public class ValidatorController { consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) @ResponseBody - @PreAuthorize("hasRole('ROLE_USER')") + @PreAuthorize("hasAuthority('REGISTERED_USER')") public ResponseEntity reSubmitJobForValidation(@PathVariable("jobId") String jobId) throws JSONException, ValidatorServiceException { return validatorService.reSubmitJobForValidation(((OIDCAuthenticationToken) SecurityContextHolder.getContext().getAuthentication()).getUserInfo().getEmail(), jobId); } @@ -78,7 +78,7 @@ public class ValidatorController { @RequestMapping(value = "/getStoredJobsNew" , method = RequestMethod.GET,produces = MediaType.APPLICATION_JSON_VALUE) @ResponseBody - @PreAuthorize("hasRole('ROLE_USER')") + @PreAuthorize("hasAuthority('REGISTERED_USER')") public List getStoredJobsNew(@RequestParam(value = "jobType", required = false) @ApiParam(value = "Equals to filter job type on validation history page") String jobType, @RequestParam("offset") @ApiParam(value = "Page number", required = true) String offset, diff --git a/src/main/java/eu/dnetlib/repo/manager/domain/RepositorySnippet.java b/src/main/java/eu/dnetlib/repo/manager/domain/RepositorySnippet.java index eb7dbf2..eb2a0ff 100644 --- a/src/main/java/eu/dnetlib/repo/manager/domain/RepositorySnippet.java +++ b/src/main/java/eu/dnetlib/repo/manager/domain/RepositorySnippet.java @@ -7,6 +7,7 @@ import java.util.Date; public class RepositorySnippet { + // Do not refactor names to keep compatibility with external api. private String id; private String officialname; private String englishname; @@ -24,7 +25,8 @@ public class RepositorySnippet { private PiwikInfo piwikInfo; - public RepositorySnippet() {} + public RepositorySnippet() { + } public String getId() { return id; diff --git a/src/main/java/eu/dnetlib/repo/manager/domain/dto/Role.java b/src/main/java/eu/dnetlib/repo/manager/domain/dto/Role.java new file mode 100644 index 0000000..e314295 --- /dev/null +++ b/src/main/java/eu/dnetlib/repo/manager/domain/dto/Role.java @@ -0,0 +1,32 @@ +package eu.dnetlib.repo.manager.domain.dto; + +import javax.xml.bind.annotation.XmlRootElement; + +@XmlRootElement +public class Role { + String name; + String description; + + public Role() {} + + public Role(String name, String description) { + this.name = name; + this.description = description; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } +} diff --git a/src/main/java/eu/dnetlib/repo/manager/domain/dto/User.java b/src/main/java/eu/dnetlib/repo/manager/domain/dto/User.java new file mode 100644 index 0000000..c14c0bb --- /dev/null +++ b/src/main/java/eu/dnetlib/repo/manager/domain/dto/User.java @@ -0,0 +1,61 @@ +package eu.dnetlib.repo.manager.domain.dto; + +import org.mitre.openid.connect.model.UserInfo; + +public class User { + + private String sub; + private String firstName; + private String lastName; + private String email; + + public User() {} + + public User(String sub, String firstName, String lastName, String email) { + this.sub = sub; + this.firstName = firstName; + this.lastName = lastName; + this.email = email; + } + + public static User from(UserInfo userInfo) { + User user = new User(); + user.setSub(user.getSub()); + user.setFirstName(userInfo.getGivenName()); + user.setLastName(userInfo.getFamilyName()); + user.setEmail(userInfo.getEmail()); + return user; + } + + public String getSub() { + return sub; + } + + public void setSub(String sub) { + this.sub = sub; + } + + public String getFirstName() { + return firstName; + } + + public void setFirstName(String firstName) { + this.firstName = firstName; + } + + public String getLastName() { + return lastName; + } + + public void setLastName(String lastName) { + this.lastName = lastName; + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } +} diff --git a/src/main/java/eu/dnetlib/repo/manager/exception/ResourceNotFoundException.java b/src/main/java/eu/dnetlib/repo/manager/exception/ResourceNotFoundException.java index 68042cf..eb7fd3c 100644 --- a/src/main/java/eu/dnetlib/repo/manager/exception/ResourceNotFoundException.java +++ b/src/main/java/eu/dnetlib/repo/manager/exception/ResourceNotFoundException.java @@ -9,6 +9,10 @@ public class ResourceNotFoundException extends Exception { super("Resource Not Found"); } + public ResourceNotFoundException(String message) { + super(message); + } + public ResourceNotFoundException(String id, String resourceType) { super(resourceType + " with id " + id + " was not found"); } diff --git a/src/main/java/eu/dnetlib/repo/manager/service/BrokerServiceImpl.java b/src/main/java/eu/dnetlib/repo/manager/service/BrokerServiceImpl.java index 6ba8f94..5edd88c 100644 --- a/src/main/java/eu/dnetlib/repo/manager/service/BrokerServiceImpl.java +++ b/src/main/java/eu/dnetlib/repo/manager/service/BrokerServiceImpl.java @@ -2,12 +2,12 @@ package eu.dnetlib.repo.manager.service; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; -import eu.dnetlib.domain.data.Repository; import eu.dnetlib.repo.manager.domain.BrokerException; import eu.dnetlib.repo.manager.domain.RepositorySnippet; import eu.dnetlib.repo.manager.domain.Term; import eu.dnetlib.repo.manager.domain.Tuple; import eu.dnetlib.repo.manager.domain.broker.*; +import org.apache.commons.lang.NotImplementedException; import org.json.JSONException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; @@ -44,11 +44,11 @@ public class BrokerServiceImpl implements BrokerService { .getLogger(BrokerServiceImpl.class); @Autowired - RestTemplate restTemplate ; + RestTemplate restTemplate; private HttpHeaders httpHeaders; - private HashMap topics = new HashMap(); + private HashMap topics = new HashMap(); @Autowired private EmailUtils emailUtils; @@ -60,29 +60,29 @@ public class BrokerServiceImpl implements BrokerService { httpHeaders.set("Content-Type", "application/json"); LOGGER.debug("Init dnet topics!"); - try (InputStream is = new URL(topicsURL).openStream() ){ + try (InputStream is = new URL(topicsURL).openStream()) { ObjectMapper mapper = new ObjectMapper(); JsonNode root = mapper.readTree(is); - for (JsonNode term : root.path("terms") ) + for (JsonNode term : root.path("terms")) topics.put(term.path("code").textValue(), parseTerm(term)); } catch (IOException e) { - LOGGER.debug("Exception on initDnetTopicsMap" , e); + LOGGER.debug("Exception on initDnetTopicsMap", e); emailUtils.reportException(e); } } private Term parseTerm(JsonNode term) { - return new Term(term.path("englishName").textValue(),term.path("nativeName").textValue(), - term.path("encoding").textValue(),term.path("code").textValue()); + return new Term(term.path("englishName").textValue(), term.path("nativeName").textValue(), + term.path("encoding").textValue(), term.path("code").textValue()); } @Override - public DatasourcesBroker getDatasourcesOfUser(String user,String includeShared,String includeByOthers) throws JSONException { + public DatasourcesBroker getDatasourcesOfUser(String user, String includeShared, String includeByOthers) throws JSONException { long start = System.currentTimeMillis(); DatasourcesBroker ret = new DatasourcesBroker(); try { - ret.setDatasourcesOfUser(getDatasourcesOfUserType(repoAPI.getRepositoriesSnippetOfUser(user,"0","100"))); + ret.setDatasourcesOfUser(getDatasourcesOfUserType(repoAPI.getRepositoriesSnippetsOfUser(user, "0", "100"))); //TODO fix bug when values are true // if (Boolean.parseBoolean(includeShared)) { // List sharedDatasourceIds = new ArrayList(); @@ -92,12 +92,12 @@ public class BrokerServiceImpl implements BrokerService { // if (Boolean.parseBoolean(includeByOthers)) { // ret.setDatasourcesOfOthers(getDatasourcesOfUserType(getRepositoriesOfUser(user))); // } - } catch (BrokerException | IOException e) { - LOGGER.debug("Exception on getDatasourcesOfUser" , e); + } catch (Exception e) { + LOGGER.debug("Exception on getDatasourcesOfUser", e); emailUtils.reportException(e); } long end = System.currentTimeMillis(); - System.out.println("Getting datasources of user in " + (end-start)+"ms"); + System.out.println("Getting datasources of user in " + (end - start) + "ms"); return ret; } @@ -117,7 +117,7 @@ public class BrokerServiceImpl implements BrokerService { new ParameterizedTypeReference>() { }); } catch (RestClientException e) { - LOGGER.debug("Exception on getTopicsForDatasource" , e); + LOGGER.debug("Exception on getTopicsForDatasource", e); emailUtils.reportException(e); throw new BrokerException(e); } @@ -128,7 +128,7 @@ public class BrokerServiceImpl implements BrokerService { @Override public EventsPage advancedShowEvents(String page, String size, - AdvQueryObject advQueryObject) throws BrokerException, JSONException ,IOException { + AdvQueryObject advQueryObject) throws BrokerException, JSONException, IOException { final String service = "/events/{page}/{pageSize}"; @@ -151,7 +151,7 @@ public class BrokerServiceImpl implements BrokerService { } ); } catch (RestClientException e) { - LOGGER.debug("Exception on advancedShowEvents" , e); + LOGGER.debug("Exception on advancedShowEvents", e); emailUtils.reportException(e); throw new BrokerException(e); } @@ -183,31 +183,11 @@ public class BrokerServiceImpl implements BrokerService { } }); long stop = System.currentTimeMillis(); - System.out.println("getDatasourcesOfUserType returned in " + (stop-start) + "ms "); + System.out.println("getDatasourcesOfUserType returned in " + (stop - start) + "ms "); return entries; } - private List getRepositoriesOfUser(String userEmail) throws JSONException { - - int page = 0; - int size = 50; - List rs ; - List resultSet = new ArrayList<>(); - - while (true){ - rs = repoAPI.getRepositoriesOfUser(userEmail, String.valueOf(page), String.valueOf(size)); - resultSet.addAll(rs); - page+=1; - if(rs.size() == 0) break; - } - return resultSet; - } - - private List getRepositoriesByIds(List sharedDatasourceIds) { - return null; - } - @Override public EventsPage showEvents(String datasourceName, String topic, @@ -230,7 +210,7 @@ public class BrokerServiceImpl implements BrokerService { new ParameterizedTypeReference() { }); } catch (RestClientException e) { - LOGGER.debug("Exception on showEvents" , e); + LOGGER.debug("Exception on showEvents", e); emailUtils.reportException(e); throw new BrokerException(e); } @@ -256,7 +236,7 @@ public class BrokerServiceImpl implements BrokerService { new ParameterizedTypeReference>>() { }); } catch (RestClientException e) { - LOGGER.debug("Exception on getSimpleSubscriptionsOfUser" , e); + LOGGER.debug("Exception on getSimpleSubscriptionsOfUser", e); emailUtils.reportException(e); throw new BrokerException(e); } @@ -266,8 +246,8 @@ public class BrokerServiceImpl implements BrokerService { @Override public Map> getSimpleSubscriptionsOfUserByRepoId(String userEmail, String repoId) throws BrokerException { Map> subscriptionsOfUser = getSimpleSubscriptionsOfUser(userEmail); - - return null; + throw new NotImplementedException(); +// return null; } @Override @@ -292,7 +272,7 @@ public class BrokerServiceImpl implements BrokerService { new ParameterizedTypeReference() { }); } catch (RestClientException e) { - LOGGER.debug("Exception on OpenaireSubscription" , e); + LOGGER.debug("Exception on OpenaireSubscription", e); emailUtils.reportException(e); throw new BrokerException(e); } @@ -316,15 +296,15 @@ public class BrokerServiceImpl implements BrokerService { new ParameterizedTypeReference() { }); } catch (RestClientException e) { - LOGGER.debug("Exception on unsubscribe" , e); + LOGGER.debug("Exception on unsubscribe", e); emailUtils.reportException(e); throw new BrokerException(e); } - return new ResponseEntity<>("OK",HttpStatus.OK); + return new ResponseEntity<>("OK", HttpStatus.OK); } @Override - public Subscription getSubscription( String subscriptionId) throws BrokerException { + public Subscription getSubscription(String subscriptionId) throws BrokerException { final String service = "/subscriptions/" + subscriptionId; //build the uri params @@ -340,7 +320,7 @@ public class BrokerServiceImpl implements BrokerService { new ParameterizedTypeReference() { }); } catch (RestClientException e) { - LOGGER.debug("Exception on getSubscription" , e); + LOGGER.debug("Exception on getSubscription", e); emailUtils.reportException(e); throw new BrokerException(e); } @@ -360,7 +340,7 @@ public class BrokerServiceImpl implements BrokerService { UriComponents uriComponents = UriComponentsBuilder .fromHttpUrl(openairePath + "/notifications/") .path("/{id}/{page}/{size}/") - .build().expand(subscriptionId,page, size).encode(); + .build().expand(subscriptionId, page, size).encode(); ResponseEntity resp; try { @@ -371,7 +351,7 @@ public class BrokerServiceImpl implements BrokerService { new ParameterizedTypeReference() { }); } catch (RestClientException e) { - LOGGER.debug("Exception on getNotificationsBySubscriptionId" , e); + LOGGER.debug("Exception on getNotificationsBySubscriptionId", e); emailUtils.reportException(e); throw new BrokerException(e); } @@ -383,16 +363,16 @@ public class BrokerServiceImpl implements BrokerService { throws BrokerException { Map> simpleSubs = getSimpleSubscriptionsOfUser(userEmail); - Map> subs = new HashMap<>(); + Map> subs = new HashMap<>(); List subscriptions = null; - for(String s:simpleSubs.keySet()){ + for (String s : simpleSubs.keySet()) { List simpleSubscriptionDescs = simpleSubs.get(s); - for(SimpleSubscriptionDesc simpleSubscriptionDesc : simpleSubscriptionDescs) { + for (SimpleSubscriptionDesc simpleSubscriptionDesc : simpleSubscriptionDescs) { subscriptions = new ArrayList<>(); subscriptions.add(getSubscription(simpleSubscriptionDesc.getId())); } - subs.put(s,subscriptions); + subs.put(s, subscriptions); } return subs; } diff --git a/src/main/java/eu/dnetlib/repo/manager/service/DashboardServiceImpl.java b/src/main/java/eu/dnetlib/repo/manager/service/DashboardServiceImpl.java index 0f16a3b..4a96da6 100644 --- a/src/main/java/eu/dnetlib/repo/manager/service/DashboardServiceImpl.java +++ b/src/main/java/eu/dnetlib/repo/manager/service/DashboardServiceImpl.java @@ -1,6 +1,5 @@ package eu.dnetlib.repo.manager.service; -import eu.dnetlib.domain.data.Repository; import eu.dnetlib.repo.manager.domain.*; import eu.dnetlib.repo.manager.domain.broker.BrowseEntry; import org.apache.log4j.Logger; @@ -27,58 +26,58 @@ public class DashboardServiceImpl implements DashboardService { @Override public List getRepositoriesSummaryInfo(String userEmail, String page, - String size){ + String size) { List repositorySummaryInfoList = new ArrayList<>(); try { - List repositoriesOfUser = repositoryService.getRepositoriesOfUser(userEmail, page, size); - for(Repository repository: repositoriesOfUser) { - RepositorySummaryInfo repositorySummaryInfo = new RepositorySummaryInfo(); - repositorySummaryInfo.setId(repository.getId()); - repositorySummaryInfo.setRepositoryName(repository.getOfficialName()); - repositorySummaryInfo.setLogoURL(repository.getLogoUrl()); + List repositoriesOfUser = repositoryService.getRepositoriesSnippetsOfUser(userEmail, page, size); + for (RepositorySnippet repository : repositoriesOfUser) { + RepositorySummaryInfo repositorySummaryInfo = new RepositorySummaryInfo(); + repositorySummaryInfo.setId(repository.getId()); + repositorySummaryInfo.setRepositoryName(repository.getOfficialname()); + repositorySummaryInfo.setLogoURL(repository.getLogoUrl()); - //TODO getRepositoryAggregations returns only the 20 more recent items. Is it positive that we will find an indexed version there? - long start = System.currentTimeMillis(); - List aggregationDetailsList = repositoryService.getRepositoryAggregations(repository.getId(),0,20); - for(AggregationDetails aggregationDetails: aggregationDetailsList) { - if(aggregationDetails.getIndexedVersion()) { - repositorySummaryInfo.setRecordsCollected(aggregationDetails.getNumberOfRecords()); - repositorySummaryInfo.setLastIndexedVersion(aggregationDetails.getDate()); - break; - } + //TODO getRepositoryAggregations returns only the 20 more recent items. Is it positive that we will find an indexed version there? + long start = System.currentTimeMillis(); + List aggregationDetailsList = repositoryService.getRepositoryAggregations(repository.getId(), 0, 20); + for (AggregationDetails aggregationDetails : aggregationDetailsList) { + if (aggregationDetails.getIndexedVersion()) { + repositorySummaryInfo.setRecordsCollected(aggregationDetails.getNumberOfRecords()); + repositorySummaryInfo.setLastIndexedVersion(aggregationDetails.getDate()); + break; } - long end = System.currentTimeMillis(); - - System.out.println("Got repo aggregations in "+ (end-start)+"ms"); - - try { - - MetricsInfo metricsInfo = repositoryService.getMetricsInfoForRepository(repository.getId()); - repositorySummaryInfo.setTotalDownloads(metricsInfo.getMetricsNumbers().getTotalDownloads()); - repositorySummaryInfo.setTotalViews(metricsInfo.getMetricsNumbers().getTotalViews()); - - } catch (RepositoryServiceException e) { - logger.error("Exception getting metrics info for repository: " + repository.getId(), e); - } - - try { - - List events = brokerService.getTopicsForDatasource(repository.getOfficialName()); - Long totalEvents = 0L; - for(BrowseEntry browseEntry: events) - totalEvents += browseEntry.getSize(); - repositorySummaryInfo.setEnrichmentEvents(totalEvents); - - - } catch (BrokerException e) { - logger.error("Exception getting broker events for repository: " + repository.getId(), e); - } - - repositorySummaryInfoList.add(repositorySummaryInfo); } + long end = System.currentTimeMillis(); + + System.out.println("Got repo aggregations in " + (end - start) + "ms"); + + try { + + MetricsInfo metricsInfo = repositoryService.getMetricsInfoForRepository(repository.getId()); + repositorySummaryInfo.setTotalDownloads(metricsInfo.getMetricsNumbers().getTotalDownloads()); + repositorySummaryInfo.setTotalViews(metricsInfo.getMetricsNumbers().getTotalViews()); + + } catch (RepositoryServiceException e) { + logger.error("Exception getting metrics info for repository: " + repository.getId(), e); + } + + try { + + List events = brokerService.getTopicsForDatasource(repository.getOfficialname()); + Long totalEvents = 0L; + for (BrowseEntry browseEntry : events) + totalEvents += browseEntry.getSize(); + repositorySummaryInfo.setEnrichmentEvents(totalEvents); + + + } catch (BrokerException e) { + logger.error("Exception getting broker events for repository: " + repository.getId(), e); + } + + repositorySummaryInfoList.add(repositorySummaryInfo); + } } catch (Exception e) { logger.error("Something baad happened!", e); diff --git a/src/main/java/eu/dnetlib/repo/manager/service/EmailUtilsImpl.java b/src/main/java/eu/dnetlib/repo/manager/service/EmailUtilsImpl.java index 975e62e..ae78561 100644 --- a/src/main/java/eu/dnetlib/repo/manager/service/EmailUtilsImpl.java +++ b/src/main/java/eu/dnetlib/repo/manager/service/EmailUtilsImpl.java @@ -33,11 +33,9 @@ public class EmailUtilsImpl implements EmailUtils { private boolean override = false, logonly = false; private String overrideEmail = null, from = null; - @Autowired - private MailLibrary mailLibrary; - - @Autowired - private CascadingPropertyLoader pLoader; + private final MailLibrary mailLibrary; + private final CascadingPropertyLoader pLoader; + private final RepositoryService repositoryService; @Value("${services.repo-manager.baseUrl}") private String baseUrl; @@ -55,7 +53,12 @@ public class EmailUtilsImpl implements EmailUtils { private String valBaseUrl; @Autowired - private RepositoryService repositoryService; + EmailUtilsImpl(MailLibrary mailLibrary, CascadingPropertyLoader pLoader, + RepositoryService repositoryService) { + this.mailLibrary = mailLibrary; + this.pLoader = pLoader; + this.repositoryService = repositoryService; + } @PostConstruct @@ -207,11 +210,11 @@ public class EmailUtilsImpl implements EmailUtils { public void sendAdminRegistrationEmail(Repository repository, Authentication authentication) throws Exception { try { String subject = "OpenAIRE content provider registration for " + - repository.getDatasourceType() + "[" + repository.getEnglishName() + "]"; + repository.getDatasourceType() + "[" + repository.getOfficialName() + "]"; String message = "Dear administrator" + ",\n" + "\n" + - "We received a request to register the " + repository.getDatasourceType() + "[" + repository.getEnglishName() + "]" + + "We received a request to register the " + repository.getDatasourceType() + "[" + repository.getOfficialName() + "]" + " to the OpenAIRE compliant list of content providers. " + "\n\n" + "User Contact: " + authentication.getName() + " (" + ((OIDCAuthenticationToken) authentication).getUserInfo().getEmail() + ")" + @@ -233,12 +236,12 @@ public class EmailUtilsImpl implements EmailUtils { public void sendUserRegistrationEmail(Repository repository, Authentication authentication) throws Exception { try { String subject = "OpenAIRE content provider registration for " + - repository.getDatasourceType() + "[" + repository.getEnglishName() + "]"; + repository.getDatasourceType() + "[" + repository.getOfficialName() + "]"; // String message = "Dear " + ((OIDCAuthenticationToken) authentication).getUserInfo().getName() + ",\n" + String message = "Dear "+SecurityContextHolder.getContext().getAuthentication().getName()+",\n" + "\n" + - "We received a request to register the " + repository.getDatasourceType() + "[" + repository.getEnglishName() + "]" + + "We received a request to register the " + repository.getDatasourceType() + "[" + repository.getOfficialName() + "]" + " to the OpenAIRE compliant list of content providers. " + "\n\n" + "Please do not reply to this message\n" + @@ -259,7 +262,7 @@ public class EmailUtilsImpl implements EmailUtils { public void sendAdminRegisterInterfaceEmail(Repository repository, String comment, RepositoryInterface repositoryInterface, Authentication authentication) throws Exception { try { String subject = "OpenAIRE new interface registration request started for " + - repository.getDatasourceType() + "[" + repository.getEnglishName() + "]"; + repository.getDatasourceType() + "[" + repository.getOfficialName() + "]"; String message = "Dear administrator" + ",\n" + "\n" + @@ -267,7 +270,7 @@ public class EmailUtilsImpl implements EmailUtils { "Base URL: " + repositoryInterface.getBaseUrl() + "\n" + "Set: " + repositoryInterface.getAccessSet() + "\n" + "Guidelines: " + repositoryInterface.getDesiredCompatibilityLevel() + "\n\n" + - "to " + repository.getDatasourceType() + "[" + repository.getEnglishName() + "].\n"; + "to " + repository.getDatasourceType() + "[" + repository.getOfficialName() + "].\n"; if (comment != null) message += "\nThe users comment was '" + comment + "'\n"; @@ -294,7 +297,7 @@ public class EmailUtilsImpl implements EmailUtils { public void sendUserRegisterInterfaceEmail(Repository repository, String comment, RepositoryInterface repositoryInterface, Authentication authentication) throws Exception { try { String subject = "OpenAIRE new interface registration request started for " + - repository.getDatasourceType() + "[" + repository.getEnglishName() + "]"; + repository.getDatasourceType() + "[" + repository.getOfficialName() + "]"; String message = "Dear "+SecurityContextHolder.getContext().getAuthentication().getName()+",\n" + "\n" + @@ -302,7 +305,7 @@ public class EmailUtilsImpl implements EmailUtils { "Base URL: " + repositoryInterface.getBaseUrl() + "\n" + "Set: " + repositoryInterface.getAccessSet() + "\n" + "Guidelines: " + repositoryInterface.getDesiredCompatibilityLevel() + "\n\n" + - "to " + repository.getDatasourceType() + "[" + repository.getEnglishName() + "].\n"; + "to " + repository.getDatasourceType() + "[" + repository.getOfficialName() + "].\n"; if (comment != null) { message += "\n Your comment was '" + comment + "'\n"; @@ -328,12 +331,12 @@ public class EmailUtilsImpl implements EmailUtils { public void sendUserRegistrationResultsSuccessEmail(String issuerEmail, String jobId, RepositoryInterface repositoryInterface, Repository repository, Authentication authentication) throws Exception { try { String subject = "OpenAIRE new interface registration request - results (success) for " + - repository.getDatasourceType() + "[" + repository.getEnglishName() + "]"; + repository.getDatasourceType() + "[" + repository.getOfficialName() + "]"; // String message = "Dear " + ((OIDCAuthenticationToken) authentication).getUserInfo().getName() + ",\n" + String message = "Dear user,\n" + "\n" + - "the compatibility test on " + "[" + repository.getEnglishName() + "]" + + "the compatibility test on " + "[" + repository.getOfficialName() + "]" + " was successful and the datasource type \""+ repository.getDatasourceType() + "\" will be prepared for aggregation in OpenAIRE."+ "\n\n" + "Please note that it usually takes about 3-4 weeks until a data source is indexed and it’s metadata visible on openaire.eu.\n\n" + @@ -361,11 +364,11 @@ public class EmailUtilsImpl implements EmailUtils { public void sendAdminRegistrationResultsSuccessEmail(String issuerEmail, String jobId,RepositoryInterface repositoryInterface, Repository repository, Authentication authentication) throws Exception { try { String subject = "OpenAIRE new interface registration request - results (success) for " + - repository.getDatasourceType() + "[" + repository.getEnglishName() + "]"; + repository.getDatasourceType() + "[" + repository.getOfficialName() + "]"; String message = "Dear admin ,\n" + "\n" + - "the compatibility test on " + "[" + repository.getEnglishName() + "]" + + "the compatibility test on " + "[" + repository.getOfficialName() + "]" + " was successful and the datasource type \""+ repository.getDatasourceType() + "\" will be prepared for aggregation in OpenAIRE."+ "\n\n" + "Please note that it usually takes about 3-4 weeks until a data source is indexed and it’s metadata visible on openaire.eu.\n\n" + @@ -394,11 +397,11 @@ public class EmailUtilsImpl implements EmailUtils { public void sendUserRegistrationResultsFailureEmail(String jobId, RepositoryInterface repositoryInterface, Repository repository, Authentication authentication) throws Exception { try { String subject = "OpenAIRE new interface registration request - results (failure) for " + - repository.getDatasourceType() + "[" + repository.getEnglishName() + "]"; + repository.getDatasourceType() + "[" + repository.getOfficialName() + "]"; // String message = "Dear " + ((OIDCAuthenticationToken) authentication).getUserInfo().getName() + ",\n" + String message = "Dear user,\n" + "\n" + - "the compatibility test on " + "[" + repository.getEnglishName() + "]" + + "the compatibility test on " + "[" + repository.getOfficialName() + "]" + " was not successful and the registration process was interrupted."+ "\n\n" + "We will check what caused the problem and get back to you within a couple of days.\n\n" + @@ -426,11 +429,11 @@ public class EmailUtilsImpl implements EmailUtils { public void sendAdminRegistrationResultsFailureEmail(String issuerEmail, String jobId, RepositoryInterface repositoryInterface, Repository repository, Authentication authentication) throws Exception { try { String subject = "OpenAIRE new interface registration request - results (failure) for " + - repository.getDatasourceType() + "[" + repository.getEnglishName() + "]"; + repository.getDatasourceType() + "[" + repository.getOfficialName() + "]"; String message = "Dear admin,\n" + "\n" + - "the compatibility test on " + "[" + repository.getEnglishName() + "]" + + "the compatibility test on " + "[" + repository.getOfficialName() + "]" + " was not successful and the registration process was interrupted."+ "\n\n" + "We will check what caused the problem and get back to you within a couple of days.\n\n" + @@ -459,12 +462,12 @@ public class EmailUtilsImpl implements EmailUtils { public void sendUserUpdateResultsSuccessEmail(String issuer, String jobId, RepositoryInterface repositoryInterface, Repository repository, Authentication authentication) throws Exception { try { String subject = "OpenAIRE interface update request - results (success) for " + - repository.getDatasourceType() + "[" + repository.getEnglishName() + "]"; + repository.getDatasourceType() + "[" + repository.getOfficialName() + "]"; // String message = "Dear " + ((OIDCAuthenticationToken) authentication).getUserInfo().getName() + ",\n" + String message = "Dear user,\n" + "\n" + - "the compatibility test on [" + repository.getEnglishName()+"] has been successful\n\n" + + "the compatibility test on [" + repository.getOfficialName()+"] has been successful\n\n" + "We will check your transmitted information and adjust the aggregation settings accordingly. Please note that it usually takes about 3-4 weeks until the changes are visible on openaire.eu."+"\n\n" + "Registration identifier in OpenAIRE: "+ repository.getNamespacePrefix()+ "\nOfficial Name:" + repository.getOfficialName() + @@ -490,11 +493,11 @@ public class EmailUtilsImpl implements EmailUtils { public void sendAdminUpdateResultsSuccessEmail(String issuerEmail, String jobId, RepositoryInterface repositoryInterface, Repository repository, Authentication authentication) throws Exception { try { String subject = "OpenAIRE interface update request - results (success) for " + - repository.getDatasourceType() + "[" + repository.getEnglishName() + "]"; + repository.getDatasourceType() + "[" + repository.getOfficialName() + "]"; String message = "Dear admin,\n" + "\n" + - "the compatibility test on [" + repository.getEnglishName()+"] has been successful\n\n" + + "the compatibility test on [" + repository.getOfficialName()+"] has been successful\n\n" + "We will check your transmitted information and adjust the aggregation settings accordingly. Please note that it usually takes about 3-4 weeks until the changes are visible on openaire.eu."+"\n\n" + "Registration identifier in OpenAIRE: "+ repository.getNamespacePrefix()+ "\nOfficial Name:" + repository.getOfficialName() + @@ -521,12 +524,12 @@ public class EmailUtilsImpl implements EmailUtils { public void sendUserUpdateResultsFailureEmail(String issuer, String jobId, RepositoryInterface repositoryInterface, Repository repository, Authentication authentication) throws Exception { try { String subject = "OpenAIRE interface update request - results (failure) for " + - repository.getDatasourceType() + "[" + repository.getEnglishName() + "]"; + repository.getDatasourceType() + "[" + repository.getOfficialName() + "]"; // String message = "Dear " + ((OIDCAuthenticationToken) authentication).getUserInfo().getName() + ",\n" + String message = "Dear user,\n" + "\n" + - "the compatibility test on " + "[" + repository.getEnglishName() + "]" + + "the compatibility test on " + "[" + repository.getOfficialName() + "]" + " was not successful."+ "\n\n" + "WWe will check your transmitted information to see what caused the problem and get back to you within a couple of days.\n\n" + @@ -554,11 +557,11 @@ public class EmailUtilsImpl implements EmailUtils { public void sendAdminUpdateResultsFailureEmail(String issuerEmail, String jobId, RepositoryInterface repositoryInterface, Repository repository, Authentication authentication) throws Exception { try { String subject = "OpenAIRE interface update request - results (failure) for " + - repository.getDatasourceType() + "[" + repository.getEnglishName() + "]"; + repository.getDatasourceType() + "[" + repository.getOfficialName() + "]"; String message = "Dear admin,\n" + "\n" + - "the compatibility test on " + "[" + repository.getEnglishName() + "]" + + "the compatibility test on " + "[" + repository.getOfficialName() + "]" + " was not successful."+ "\n\n" + "WWe will check your transmitted information to see what caused the problem and get back to you within a couple of days.\n\n" + @@ -653,11 +656,11 @@ public class EmailUtilsImpl implements EmailUtils { public void sendAdminUpdateRepositoryInfoEmail(Repository repository, Authentication authentication) throws Exception { try { String subject = "OpenAIRE content provider update information for " + - repository.getDatasourceType() + "[" + repository.getEnglishName() + "]"; + repository.getDatasourceType() + "[" + repository.getOfficialName() + "]"; String message = "Dear administrator" + ",\n" + "\n" + - "We received a request to update the basic information for " + repository.getDatasourceType() + "[" + repository.getEnglishName() + "].\n\n" + + "We received a request to update the basic information for " + repository.getDatasourceType() + "[" + repository.getOfficialName() + "].\n\n" + "Please do not reply to this message\n" + "This message has been generated automatically.\n\n" + "Regards,\n" + @@ -675,12 +678,12 @@ public class EmailUtilsImpl implements EmailUtils { public void sendUserUpdateRepositoryInfoEmail(Repository repository, Authentication authentication) throws Exception { try { String subject = "OpenAIRE content provider update information for " + - repository.getDatasourceType() + "[" + repository.getEnglishName() + "]"; + repository.getDatasourceType() + "[" + repository.getOfficialName() + "]"; // String message = "Dear " + ((OIDCAuthenticationToken) authentication).getUserInfo().getName() + ",\n" + String message = "Dear user,\n" + "\n" + - "We received a request to update the basic information for " + repository.getDatasourceType() + "[" + repository.getEnglishName() + "].\n\n" + + "We received a request to update the basic information for " + repository.getDatasourceType() + "[" + repository.getOfficialName() + "].\n\n" + "Please do not reply to this message\n" + "This message has been generated automatically.\n\n" + "If you have any questions, write to 'helpdesk@openaire.eu'. \n\n" + @@ -699,7 +702,7 @@ public class EmailUtilsImpl implements EmailUtils { public void sendAdminUpdateInterfaceEmail(Repository repository, String comment, RepositoryInterface repositoryInterface, Authentication authentication) throws Exception { try { String subject = "OpenAIRE interface update request started for " + - repository.getDatasourceType() + "[" + repository.getEnglishName() + "]"; + repository.getDatasourceType() + "[" + repository.getOfficialName() + "]"; String message = "Dear administrator" + ",\n" + "\n" + @@ -707,7 +710,7 @@ public class EmailUtilsImpl implements EmailUtils { "Base URL: " + repositoryInterface.getBaseUrl() + "\n" + "Set: " + repositoryInterface.getAccessSet() + "\n" + "Guidelines: " + repositoryInterface.getDesiredCompatibilityLevel() + "\n\n" + - "for " + repository.getDatasourceType() + "[" + repository.getEnglishName() + "].\n"; + "for " + repository.getDatasourceType() + "[" + repository.getOfficialName() + "].\n"; if (comment != null) message += "\nThe users comment was '" + comment + "'\n"; @@ -732,7 +735,7 @@ public class EmailUtilsImpl implements EmailUtils { public void sendUserUpdateInterfaceEmail(Repository repository, String comment, RepositoryInterface repositoryInterface, Authentication authentication) throws Exception { try { String subject = "OpenAIRE interface update request started for " + - repository.getDatasourceType() + "[" + repository.getEnglishName() + "]"; + repository.getDatasourceType() + "[" + repository.getOfficialName() + "]"; // String message = "Dear " + ((OIDCAuthenticationToken) authentication).getUserInfo().getName() + ",\n" + String message = "Dear user,\n" + @@ -741,7 +744,7 @@ public class EmailUtilsImpl implements EmailUtils { "Base URL: " + repositoryInterface.getBaseUrl() + "\n" + "Set: " + repositoryInterface.getAccessSet() + "\n" + "Guidelines: " + repositoryInterface.getDesiredCompatibilityLevel() + "\n\n" + - "for " + repository.getDatasourceType() + "[" + repository.getEnglishName() + "].\n"; + "for " + repository.getDatasourceType() + "[" + repository.getOfficialName() + "].\n"; if (comment != null) { message += "\n Your comment was '" + comment + "'\n"; diff --git a/src/main/java/eu/dnetlib/repo/manager/service/PiWikServiceImpl.java b/src/main/java/eu/dnetlib/repo/manager/service/PiWikServiceImpl.java index 5f6ae13..a388ba4 100644 --- a/src/main/java/eu/dnetlib/repo/manager/service/PiWikServiceImpl.java +++ b/src/main/java/eu/dnetlib/repo/manager/service/PiWikServiceImpl.java @@ -75,7 +75,7 @@ public class PiWikServiceImpl implements PiWikService { } @Override - @PreAuthorize("hasRole('ROLE_ADMIN') or hasRole('ROLE_PROVIDE_ADMIN') or (hasRole('ROLE_USER') and #piwikInfo.requestorEmail == authentication.userInfo.email)") + @PreAuthorize("hasAuthority('SUPER_ADMINISTRATOR') or hasAuthority('CONTENT_PROVIDER_DASHBOARD_ADMINISTRATOR') or (hasAuthority('REGISTERED_USER') and #piwikInfo.requestorEmail == authentication.userInfo.email)") public PiwikInfo savePiwikInfo(PiwikInfo piwikInfo) { JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource); jdbcTemplate.update(INSERT_PIWIK_INFO, new Object[]{piwikInfo.getRepositoryId(), piwikInfo.getSiteId(), piwikInfo.getRequestorName(), @@ -144,7 +144,7 @@ public class PiWikServiceImpl implements PiWikService { } @Override - @PreAuthorize("hasRole('ROLE_ADMIN') or hasRole('ROLE_PROVIDE_ADMIN')") + @PreAuthorize("hasAuthority('SUPER_ADMINISTRATOR') or hasAuthority('CONTENT_PROVIDER_DASHBOARD_ADMINISTRATOR')") public ResponseEntity approvePiwikSite(String repositoryId) { new JdbcTemplate(dataSource).update(APPROVE_PIWIK_SITE, new Object[] {repositoryId}, new int[] {Types.VARCHAR}); return new ResponseEntity<>("OK",HttpStatus.OK); @@ -158,7 +158,7 @@ public class PiWikServiceImpl implements PiWikService { } @Override - @PreAuthorize("hasRole('ROLE_ADMIN') or hasRole('ROLE_PROVIDE_ADMIN')") + @PreAuthorize("hasAuthority('SUPER_ADMINISTRATOR') or hasAuthority('CONTENT_PROVIDER_DASHBOARD_ADMINISTRATOR')") public ResponseEntity markPiwikSiteAsValidated(String repositoryId) throws RepositoryServiceException { try { approvePiwikSite(repositoryId); @@ -179,7 +179,7 @@ public class PiWikServiceImpl implements PiWikService { } @Override - @PreAuthorize("hasRole('ROLE_ADMIN') or hasRole('ROLE_PROVIDE_ADMIN') or (hasRole('ROLE_USER') and #piwikInfo.requestorEmail == authentication.userInfo.email)") + @PreAuthorize("hasAuthority('SUPER_ADMINISTRATOR') or hasAuthority('CONTENT_PROVIDER_DASHBOARD_ADMINISTRATOR') or (hasAuthority('REGISTERED_USER') and #piwikInfo.requestorEmail == authentication.userInfo.email)") public PiwikInfo enableMetricsForRepository(String officialName, String repoWebsite, PiwikInfo piwikInfo) throws RepositoryServiceException { diff --git a/src/main/java/eu/dnetlib/repo/manager/service/RepositoryService.java b/src/main/java/eu/dnetlib/repo/manager/service/RepositoryService.java index ea630e0..aca2981 100644 --- a/src/main/java/eu/dnetlib/repo/manager/service/RepositoryService.java +++ b/src/main/java/eu/dnetlib/repo/manager/service/RepositoryService.java @@ -14,29 +14,46 @@ import java.util.Map; public interface RepositoryService { - Country[] getCountries() ; + // TODO: move this elsewhere + Country[] getCountries(); + + List getRepositories(List ids) throws JSONException; + + List getRepositories(List ids, int page, int size) throws JSONException; + + List getRepositoriesSnippets(List ids) throws Exception; + + List getRepositoriesSnippets(List ids, int page, int size) throws Exception; List getRepositoriesByCountry(String country, String mode, Boolean managed) throws JSONException, IOException; + // TODO: remove? + List getRepositoriesOfUser(String page, String size) throws JSONException, IOException; + + // TODO: remove? List getRepositoriesOfUser(String userEmail, String page, String size) throws JSONException, IOException; - List getRepositoriesSnippetOfUser(String userEmail, String page, String size) throws IOException, JSONException; + List getRepositoriesSnippetsOfUser(String page, String size) throws Exception; + + List getRepositoriesSnippetsOfUser(String userEmail, String page, String size) throws Exception; + + RepositorySnippet getRepositorySnippetById(String id) throws JSONException, ResourceNotFoundException; Repository getRepositoryById(String id) throws JSONException, ResourceNotFoundException; List getRepositoryAggregations(String id, int from, int size) throws JSONException; - Map> getRepositoryAggregationsByYear(String id) throws JSONException; + Map> getRepositoryAggregationsByYear(String id) throws JSONException; List getRepositoriesByName(String name, String page, String size) throws JSONException; List searchRegisteredRepositories(String country, String typology, String englishName, - String officialName, String requestSortBy, String order, - int page, int pageSize) throws Exception; + String officialName, String requestSortBy, String order, + int page, int pageSize) throws Exception; List getRepositoryInterface(String id) throws JSONException; @@ -59,7 +76,7 @@ public interface RepositoryService { List getUrlsOfUserRepos(String user_email, String page, - String size) throws JSONException; + String size); List getDatasourceVocabularies(String mode); @@ -71,7 +88,7 @@ public interface RepositoryService { MetricsInfo getMetricsInfoForRepository(String repoId) throws RepositoryServiceException; - Map getListLatestUpdate(String mode) throws RepositoryServiceException, JSONException; + Map getListLatestUpdate(String mode) throws JSONException; RepositoryInterface updateRepositoryInterface(String repoId, String registeredBy, String comment, RepositoryInterface repositoryInterface) throws Exception; diff --git a/src/main/java/eu/dnetlib/repo/manager/service/RepositoryServiceImpl.java b/src/main/java/eu/dnetlib/repo/manager/service/RepositoryServiceImpl.java index 6e2c2a8..e88d1bc 100644 --- a/src/main/java/eu/dnetlib/repo/manager/service/RepositoryServiceImpl.java +++ b/src/main/java/eu/dnetlib/repo/manager/service/RepositoryServiceImpl.java @@ -1,13 +1,21 @@ package eu.dnetlib.repo.manager.service; import com.fasterxml.jackson.databind.ObjectMapper; +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; import eu.dnetlib.api.functionality.ValidatorServiceException; import eu.dnetlib.domain.data.Repository; import eu.dnetlib.domain.data.RepositoryInterface; import eu.dnetlib.domain.enabling.Vocabulary; import eu.dnetlib.domain.functionality.validator.JobForValidation; import eu.dnetlib.repo.manager.domain.*; +import eu.dnetlib.repo.manager.domain.dto.Role; import eu.dnetlib.repo.manager.exception.ResourceNotFoundException; +import eu.dnetlib.repo.manager.service.aai.registry.AaiRegistryService; +import eu.dnetlib.repo.manager.service.security.AuthoritiesUpdater; +import eu.dnetlib.repo.manager.service.security.AuthorizationService; +import eu.dnetlib.repo.manager.service.security.RoleMappingService; import eu.dnetlib.repo.manager.utils.Converter; import gr.uoa.di.driver.enabling.vocabulary.VocabularyLoader; import org.apache.commons.codec.digest.DigestUtils; @@ -15,14 +23,17 @@ import org.apache.log4j.Logger; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; +import org.mitre.openid.connect.model.OIDCAuthenticationToken; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Lazy; import org.springframework.core.ParameterizedTypeReference; import org.springframework.http.*; import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.stereotype.Service; +import org.springframework.web.client.HttpClientErrorException; import org.springframework.web.client.RestClientException; import org.springframework.web.client.RestTemplate; import org.springframework.web.util.UriComponents; @@ -38,49 +49,67 @@ import java.util.stream.Collectors; @Service("repositoryService") public class RepositoryServiceImpl implements RepositoryService { + private static final Logger LOGGER = Logger.getLogger(RepositoryServiceImpl.class); + + private final AuthorizationService authorizationService; + private final RoleMappingService roleMappingService; + 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}") private String baseAddress; @Value("${services.repo-manager.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}") private String usageStatisticsDiagramsBaseURL; @Value("${services.repomanager.usageStatisticsNumbersBaseURL}") private String usageStatisticsNumbersBaseURL; - @Autowired - private VocabularyLoader vocabularyLoader; + + private static final Map> dataSourceClass = new HashMap<>(); + private static final Map invertedDataSourceClass = new HashMap<>(); + + + private final String[] vocabularyNames = {"dnet:countries", "dnet:datasource_typologies", "dnet:compatibilityLevel"}; + private final Map vocabularyMap = new ConcurrentHashMap<>(); + private final Map countriesMap = new HashMap<>(); + private final Map inverseCountriesMap = new HashMap<>(); + + private HttpHeaders httpHeaders; @Autowired - private PiWikService piWikService; - - @Autowired - private EmailUtils emailUtils; - - @Autowired - ValidatorService validatorService; - - - private Map vocabularyMap = new ConcurrentHashMap<>(); - - private Map countriesMap = new HashMap<>(); - private Map inverseCountriesMap = new HashMap<>(); - - private static Map> dataSourceClass = new HashMap<>(); - - private static Map invertedDataSourceClass = new HashMap<>(); + public RepositoryServiceImpl(AuthorizationService authorizationService, + RoleMappingService roleMappingService, + AaiRegistryService registryCalls, + AuthoritiesUpdater authoritiesUpdater, + VocabularyLoader vocabularyLoader, + RestTemplate restTemplate, + @Lazy EmailUtils emailUtils, + @Lazy ValidatorService validatorService, + @Lazy PiWikService piWikService) { + this.authorizationService = authorizationService; + this.roleMappingService = roleMappingService; + this.registryCalls = registryCalls; + this.authoritiesUpdater = authoritiesUpdater; + this.vocabularyLoader = vocabularyLoader; + this.piWikService = piWikService; + this.emailUtils = emailUtils; + this.validatorService = validatorService; + this.restTemplate = restTemplate; + } + private String getAuthenticatedUserEmail() { + OIDCAuthenticationToken authenticationToken = (OIDCAuthenticationToken) SecurityContextHolder.getContext().getAuthentication(); + return authenticationToken.getUserInfo().getEmail(); + } @PostConstruct @@ -88,21 +117,21 @@ public class RepositoryServiceImpl implements RepositoryService { LOGGER.debug("Initialization method of repository api!"); LOGGER.debug("Updated version!"); - dataSourceClass.put("opendoar",Arrays.asList("pubsrepository::institutional","pubsrepository::thematic","pubsrepository::unknown","pubsrepository::mock")); + dataSourceClass.put("opendoar", Arrays.asList("pubsrepository::institutional", "pubsrepository::thematic", "pubsrepository::unknown", "pubsrepository::mock")); dataSourceClass.put("re3data", Collections.singletonList("datarepository::unknown")); dataSourceClass.put("journal", Collections.singletonList("pubsrepository::journal")); - dataSourceClass.put("aggregator",Arrays.asList("aggregator::pubsrepository::institutional","aggregator::pubsrepository::journals","aggregator::datarepository", "aggregator::pubsrepository::unknown")); + dataSourceClass.put("aggregator", Arrays.asList("aggregator::pubsrepository::institutional", "aggregator::pubsrepository::journals", "aggregator::datarepository", "aggregator::pubsrepository::unknown")); - invertedDataSourceClass.put("pubsrepository::institutional","opendoar"); - invertedDataSourceClass.put("pubsrepository::thematic","opendoar"); - invertedDataSourceClass.put("pubsrepository::unknown","opendoar"); - invertedDataSourceClass.put("pubsrepository::mock","opendoar"); - invertedDataSourceClass.put("datarepository::unknown","re3data"); - invertedDataSourceClass.put("pubsrepository::journal","journal"); - invertedDataSourceClass.put("aggregator::pubsrepository::institutional","aggregator"); - invertedDataSourceClass.put("aggregator::pubsrepository::journals","aggregator"); - invertedDataSourceClass.put("aggregator::datarepository","aggregator"); - invertedDataSourceClass.put("aggregator::pubsrepository::unknown","aggregator"); + invertedDataSourceClass.put("pubsrepository::institutional", "opendoar"); + invertedDataSourceClass.put("pubsrepository::thematic", "opendoar"); + invertedDataSourceClass.put("pubsrepository::unknown", "opendoar"); + invertedDataSourceClass.put("pubsrepository::mock", "opendoar"); + invertedDataSourceClass.put("datarepository::unknown", "re3data"); + invertedDataSourceClass.put("pubsrepository::journal", "journal"); + invertedDataSourceClass.put("aggregator::pubsrepository::institutional", "aggregator"); + invertedDataSourceClass.put("aggregator::pubsrepository::journals", "aggregator"); + invertedDataSourceClass.put("aggregator::datarepository", "aggregator"); + invertedDataSourceClass.put("aggregator::pubsrepository::unknown", "aggregator"); httpHeaders = new HttpHeaders(); @@ -128,6 +157,83 @@ public class RepositoryServiceImpl implements RepositoryService { .build().encode(); return restTemplate.getForObject(uriComponents.toUri(), Country[].class); } + + // FIXME: with the new roles of the users the "requestFilter.setRegisteredby(userEmail)" can no longer be used + // and the "requestFilter.setId(repoId)" should return only one result at a time, thus, + // another way for paging must be implemented. + @Override + public List getRepositories(List ids) throws JSONException { + return getRepositories(ids, 0, 10); + } + + // FIXME: with the new roles of the users the "requestFilter.setRegisteredby(userEmail)" can no longer be used + // and the "requestFilter.setId(repoId)" should return only one result at a time, thus, + // another way for paging must be implemented. + @Override + public List getRepositories(List ids, int page, int size) throws JSONException { + List repos = new ArrayList<>(); + LOGGER.debug("Retreiving repositories with ids : " + String.join(", ", ids)); + UriComponents uriComponents = searchDatasource(Integer.toString(Math.abs(page)), Integer.toString(Math.abs(size))); + RequestFilter requestFilter = new RequestFilter(); + + try { + for (String repoId : ids) { + requestFilter.setId(repoId); + String rs = restTemplate.postForObject(uriComponents.toUri(), requestFilter, String.class); + + repos.addAll(Converter.jsonToRepositoryList(new JSONObject(rs))); + } + } catch (JSONException e) { + LOGGER.debug("Exception on getRepositoriesOfUser", e); + emailUtils.reportException(e); + throw e; + } + + for (Repository r : repos) + r.setPiwikInfo(piWikService.getPiwikSiteForRepo(r.getId())); + return repos; + } + + // FIXME: with the new roles of the users the "requestFilter.setRegisteredby(userEmail)" can no longer be used + // and the "requestFilter.setId(repoId)" should return only one result at a time, thus, + // another way for paging must be implemented. + @Override + public List getRepositoriesSnippets(List ids) throws Exception { + return getRepositoriesSnippets(ids, 0, 10); + } + + // FIXME: with the new roles of the users the "requestFilter.setRegisteredby(userEmail)" can no longer be used + // and the "requestFilter.setId(repoId)" should return only one result at a time, thus, + // another way for paging must be implemented. + @Override + public List getRepositoriesSnippets(List ids, int page, int size) throws Exception { + List resultSet = new ArrayList<>(); + ObjectMapper mapper = new ObjectMapper(); + + // here page should be 0 + UriComponents uriComponents = searchSnipperDatasource(Integer.toString(Math.abs(page)), Integer.toString(Math.abs(size))); + RequestFilter requestFilter = new RequestFilter(); + + try { + for (String repoId : ids) { + requestFilter.setId(repoId); + + String rs = restTemplate.postForObject(uriComponents.toUri(), requestFilter, String.class); + JSONArray jsonArray = (JSONArray) new JSONObject(rs).get("datasourceInfo"); + resultSet.addAll(mapper.readValue(String.valueOf(jsonArray), + mapper.getTypeFactory().constructCollectionType(List.class, RepositorySnippet.class))); + } + } catch (Exception e) { + LOGGER.debug("Exception on getRepositoriesSnippetOfUser", e); + throw e; + } + + LOGGER.debug("resultSet:" + resultSet); + resultSet.parallelStream().forEach(repositorySnippet -> { + repositorySnippet.setPiwikInfo(piWikService.getPiwikSiteForRepo(repositorySnippet.getId())); + }); + return resultSet; + } @Override @@ -151,32 +257,32 @@ public class RepositoryServiceImpl implements RepositoryService { LOGGER.debug("Country code equals : " + country); LOGGER.debug("Filter mode equals : " + filterKey); - UriComponents uriComponents = searchSnipperDatasource(String.valueOf(page),String.valueOf(size)); + UriComponents uriComponents = searchSnipperDatasource(String.valueOf(page), String.valueOf(size)); RequestFilter requestFilter = new RequestFilter(); requestFilter.setCountry(country); requestFilter.setCollectedfrom(filterKey); - try{ - String rs = restTemplate.postForObject(uriComponents.toUri(),requestFilter, String.class); + try { + String rs = restTemplate.postForObject(uriComponents.toUri(), requestFilter, String.class); JSONArray jsonArray = (JSONArray) new JSONObject(rs).get("datasourceInfo"); - while (jsonArray.length() > 0 ) { + while (jsonArray.length() > 0) { resultSet.addAll(mapper.readValue(String.valueOf(jsonArray), mapper.getTypeFactory().constructCollectionType(List.class, RepositorySnippet.class))); page += 1; - uriComponents = searchSnipperDatasource(String.valueOf(page),String.valueOf(size)); - rs = restTemplate.postForObject(uriComponents.toUri(),requestFilter, String.class); + uriComponents = searchSnipperDatasource(String.valueOf(page), String.valueOf(size)); + rs = restTemplate.postForObject(uriComponents.toUri(), requestFilter, String.class); jsonArray = (JSONArray) new JSONObject(rs).get("datasourceInfo"); } return resultSet; - }catch (Exception e){ - LOGGER.debug("Exception on getRepositoriesByCountry" , e); + } catch (Exception e) { + LOGGER.debug("Exception on getRepositoriesByCountry", e); // emailUtils.reportException(e); throw e; } } public List searchRegisteredRepositories(String country, String typology, String englishName, - String officialName, String requestSortBy, String order, int page, int pageSize) throws Exception { + String officialName, String requestSortBy, String order, int page, int pageSize) throws Exception { LOGGER.debug("Searching registered repositories"); @@ -192,14 +298,14 @@ public class RepositoryServiceImpl implements RepositoryService { requestFilter.setEnglishname(englishName); try { - String rs = restTemplate.postForObject(uriComponents.toUri(),requestFilter, String.class); + String rs = restTemplate.postForObject(uriComponents.toUri(), requestFilter, String.class); JSONArray jsonArray = (JSONArray) new JSONObject(rs).get("datasourceInfo"); - resultSet.addAll(mapper.readValue(String.valueOf(jsonArray), mapper.getTypeFactory().constructCollectionType(List.class, RepositorySnippet.class))); + resultSet.addAll(mapper.readValue(String.valueOf(jsonArray), mapper.getTypeFactory().constructCollectionType(List.class, RepositorySnippet.class))); - return resultSet; - }catch (Exception e){ - LOGGER.error("Error searching registered datasources" , e); + return resultSet; + } catch (Exception e) { + LOGGER.error("Error searching registered datasources", e); throw e; } } @@ -207,9 +313,9 @@ public class RepositoryServiceImpl implements RepositoryService { private Repository updateRepositoryInfo(Repository r) throws JSONException { /* - * from datasource class - * we get the datasource type form the inverted map - * */ + * from datasource class + * we get the datasource type form the inverted map + * */ r.setDatasourceType(getRepositoryType(r.getDatasourceClass())); r.setInterfaces(this.getRepositoryInterface(r.getId())); r.setPiwikInfo(piWikService.getPiwikSiteForRepo(r.getId())); @@ -230,79 +336,78 @@ public class RepositoryServiceImpl implements RepositoryService { } @Override - public List getRepositoriesOfUser(String userEmail, - String page, - String size) throws JSONException { - - LOGGER.debug("Retreiving repositories of user : " + userEmail ); - UriComponents uriComponents = searchDatasource(page,size); - RequestFilter requestFilter = new RequestFilter(); - requestFilter.setRegisteredby(userEmail); - - try{ - String rs = restTemplate.postForObject(uriComponents.toUri(),requestFilter, String.class); - - List repos = Converter.jsonToRepositoryList(new JSONObject(rs)); - for (Repository r : repos) - r.setPiwikInfo(piWikService.getPiwikSiteForRepo(r.getId())); - return repos; - }catch (Exception e){ - LOGGER.debug("Exception on getRepositoriesOfUser" , e); - emailUtils.reportException(e); - throw e; - } + public List getRepositoriesOfUser(String page, String size) throws JSONException { + String userEmail = ((OIDCAuthenticationToken) SecurityContextHolder.getContext().getAuthentication()).getUserInfo().getEmail(); + LOGGER.debug("Retreiving repositories of authenticated user : " + userEmail); + Collection repoIds = roleMappingService.getRepoIdsByRoleIds(authorizationService.getUserRoles()); + return getRepositories(new ArrayList<>(repoIds)); } @Override - public List getRepositoriesSnippetOfUser(String userEmail, String page, String size) throws IOException, JSONException { - List resultSet = new ArrayList<>(); - ObjectMapper mapper = new ObjectMapper(); - - UriComponents uriComponents = searchSnipperDatasource(page,size); - RequestFilter requestFilter = new RequestFilter(); - requestFilter.setRegisteredby(userEmail); - - try{ - String rs = restTemplate.postForObject(uriComponents.toUri(),requestFilter, String.class); - JSONArray jsonArray = (JSONArray) new JSONObject(rs).get("datasourceInfo"); - while (jsonArray.length() > 0 ) { - resultSet.addAll(mapper.readValue(String.valueOf(jsonArray), - mapper.getTypeFactory().constructCollectionType(List.class, RepositorySnippet.class))); - page += 1; - uriComponents = searchSnipperDatasource(page,size); - rs = restTemplate.postForObject(uriComponents.toUri(),requestFilter, String.class); - jsonArray = (JSONArray) new JSONObject(rs).get("datasourceInfo"); - } - resultSet.parallelStream().forEach(repositorySnippet -> { - repositorySnippet.setPiwikInfo(piWikService.getPiwikSiteForRepo(repositorySnippet.getId())); - }); - return resultSet; - }catch (Exception e){ - LOGGER.debug("Exception on getRepositoriesByCountry" , e); - throw e; - } + public List getRepositoriesOfUser(String userEmail, String page, String size) throws JSONException { + LOGGER.debug("Retreiving repositories of authenticated user : " + userEmail); + Collection repoIds = roleMappingService.getRepoIdsByRoleIds(authorizationService.getUserRoles(userEmail)); + return getRepositories(new ArrayList<>(repoIds)); } @Override - public Repository getRepositoryById(String id) throws JSONException,ResourceNotFoundException { + public List getRepositoriesSnippetsOfUser(String page, String size) throws Exception { + Collection repoIds = roleMappingService.getRepoIdsByRoleIds(authorizationService.getUserRoles()); + return getRepositoriesSnippets(new ArrayList<>(repoIds)); + } - LOGGER.debug("Retreiving repositories with id : " + id ); - Repository repo = null; - UriComponents uriComponents = searchDatasource("0","100"); + @Override + public List getRepositoriesSnippetsOfUser(String userEmail, String page, String size) throws Exception { + Collection repoIds = roleMappingService.getRepoIdsByRoleIds(authorizationService.getUserRoles(userEmail)); + return getRepositoriesSnippets(new ArrayList<>(repoIds)); + } + + @Override + public RepositorySnippet getRepositorySnippetById(String id) throws JSONException, ResourceNotFoundException { + + LOGGER.debug("Retreiving repositories with id : " + id); + RepositorySnippet repo = null; + UriComponents uriComponents = searchSnipperDatasource("0", "100"); RequestFilter requestFilter = new RequestFilter(); requestFilter.setId(id); - try{ - String rs = restTemplate.postForObject(uriComponents.toUri(),requestFilter, String.class); + try { + String rs = restTemplate.postForObject(uriComponents.toUri(), requestFilter, String.class); JSONArray jsonArray = (JSONArray) new JSONObject(rs).get("datasourceInfo"); - if(jsonArray.length() == 0) + if (jsonArray.length() == 0) + throw new ResourceNotFoundException(); + + repo = Converter.jsonToRepositorySnippetObject(jsonArray.getJSONObject(0)); + return repo; + } catch (JSONException e) { + LOGGER.debug("Exception on getRepositoryById", e); + emailUtils.reportException(e); + throw e; + } + + } + + @Override + public Repository getRepositoryById(String id) throws JSONException, ResourceNotFoundException { + + LOGGER.debug("Retreiving repositories with id : " + id); + Repository repo = null; + UriComponents uriComponents = searchDatasource("0", "100"); + RequestFilter requestFilter = new RequestFilter(); + requestFilter.setId(id); + + try { + String rs = restTemplate.postForObject(uriComponents.toUri(), requestFilter, String.class); + JSONArray jsonArray = (JSONArray) new JSONObject(rs).get("datasourceInfo"); + + if (jsonArray.length() == 0) throw new ResourceNotFoundException(); repo = Converter.jsonToRepositoryObject(jsonArray.getJSONObject(0)); return updateRepositoryInfo(repo); - }catch (JSONException e){ - LOGGER.debug("Exception on getRepositoryById" , e); + } catch (JSONException e) { + LOGGER.debug("Exception on getRepositoryById", e); emailUtils.reportException(e); throw e; } @@ -313,8 +418,8 @@ public class RepositoryServiceImpl implements RepositoryService { @Override public List getRepositoryAggregations(String id, int from, int size) throws JSONException { - LOGGER.debug("Retreiving aggregations for repository with id : " + id ); - UriComponents uriComponents = searchDatasource(from+"",size+""); + LOGGER.debug("Retreiving aggregations for repository with id : " + id); + UriComponents uriComponents = searchDatasource(from + "", size + ""); RequestFilter requestFilter = new RequestFilter(); requestFilter.setId(id); @@ -322,26 +427,26 @@ public class RepositoryServiceImpl implements RepositoryService { try { long start = System.currentTimeMillis(); - String rs = restTemplate.postForObject(uriComponents.toUri(),requestFilter, String.class); + String rs = restTemplate.postForObject(uriComponents.toUri(), requestFilter, String.class); long end = System.currentTimeMillis(); - System.out.println("Aggregations request through rest template took " + (end-start)+"ms"); + System.out.println("Aggregations request through rest template took " + (end - start) + "ms"); JSONObject repository = new JSONObject(rs); - if(repository.getJSONArray("datasourceInfo").length() == 0) + if (repository.getJSONArray("datasourceInfo").length() == 0) return aggregationHistory; start = System.currentTimeMillis(); aggregationHistory.addAll(Converter.getAggregationHistoryFromJson(repository.getJSONArray("datasourceInfo").getJSONObject(0))); end = System.currentTimeMillis(); - System.out.println("Getting aggregations history from json " + (end-start)+"ms"); - return aggregationHistory.size() == 0? aggregationHistory : aggregationHistory.stream() - .sorted(Comparator.comparing(AggregationDetails::getDate).reversed()) - .limit(size) - .collect(Collectors.toList()); + System.out.println("Getting aggregations history from json " + (end - start) + "ms"); + return aggregationHistory.size() == 0 ? aggregationHistory : aggregationHistory.stream() + .sorted(Comparator.comparing(AggregationDetails::getDate).reversed()) + .limit(size) + .collect(Collectors.toList()); } catch (JSONException e) { - LOGGER.debug("Exception on getRepositoryAggregations" , e); + LOGGER.debug("Exception on getRepositoryAggregations", e); emailUtils.reportException(e); throw e; } @@ -350,38 +455,38 @@ public class RepositoryServiceImpl implements RepositoryService { @Override public Map> getRepositoryAggregationsByYear(String id) throws JSONException { - LOGGER.debug("Retreiving aggregations (by year) for repository with id : " + id ); - UriComponents uriComponents = searchDatasource("0","100"); + LOGGER.debug("Retreiving aggregations (by year) for repository with id : " + id); + UriComponents uriComponents = searchDatasource("0", "100"); RequestFilter requestFilter = new RequestFilter(); requestFilter.setId(id); List aggregationHistory = new ArrayList<>(); Map> aggregationByYear = new HashMap<>(); try { - String rs = restTemplate.postForObject(uriComponents.toUri(),requestFilter, String.class); + String rs = restTemplate.postForObject(uriComponents.toUri(), requestFilter, String.class); JSONObject repository = new JSONObject(rs); - if(repository.getJSONArray("datasourceInfo").length() == 0) + if (repository.getJSONArray("datasourceInfo").length() == 0) return aggregationByYear; aggregationHistory.addAll(Converter.getAggregationHistoryFromJson(repository.getJSONArray("datasourceInfo").getJSONObject(0))); - return aggregationHistory.size() == 0? aggregationByYear:createYearMap(aggregationHistory); + return aggregationHistory.size() == 0 ? aggregationByYear : createYearMap(aggregationHistory); } catch (JSONException e) { - LOGGER.debug("Exception on getRepositoryAggregations" , e); + LOGGER.debug("Exception on getRepositoryAggregations", e); emailUtils.reportException(e); throw e; } } - private Map> createYearMap(List aggregationHistory) { + private Map> createYearMap(List aggregationHistory) { Map> aggregationByYear; aggregationHistory = aggregationHistory.stream() - .sorted(Comparator.comparing(AggregationDetails::getDate).reversed()) - .collect(Collectors.toList()); + .sorted(Comparator.comparing(AggregationDetails::getDate).reversed()) + .collect(Collectors.toList()); - return aggregationHistory.stream() - .collect(Collectors.groupingBy(AggregationDetails::getYear)); + return aggregationHistory.stream() + .collect(Collectors.groupingBy(AggregationDetails::getYear)); } @@ -390,19 +495,19 @@ public class RepositoryServiceImpl implements RepositoryService { String page, String size) throws JSONException { - LOGGER.debug("Retreiving repositories with official name : " + name ); - UriComponents uriComponents = searchDatasource("0","100"); + LOGGER.debug("Retreiving repositories with official name : " + name); + UriComponents uriComponents = searchDatasource("0", "100"); RequestFilter requestFilter = new RequestFilter(); requestFilter.setOfficialname(name); - try{ - String rs = restTemplate.postForObject(uriComponents.toUri(),requestFilter, String.class); + try { + String rs = restTemplate.postForObject(uriComponents.toUri(), requestFilter, String.class); List repos = Converter.jsonToRepositoryList(new JSONObject(rs)); for (Repository r : repos) updateRepositoryInfo(r); return repos; - }catch (Exception e){ - LOGGER.debug("Exception on getRepositoriesByName" , e); + } catch (Exception e) { + LOGGER.debug("Exception on getRepositoriesByName", e); emailUtils.reportException(e); throw e; } @@ -417,11 +522,11 @@ public class RepositoryServiceImpl implements RepositoryService { .path("/{id}") .build().expand(id).encode(); - try{ + try { String rs = restTemplate.getForObject(uriComponents.toUri(), String.class); return Converter.jsonToRepositoryInterfaceList(new JSONObject(rs)); - }catch (Exception e ){ - LOGGER.debug("Exception on getRepositoryInterface" , e); + } catch (Exception e) { + LOGGER.debug("Exception on getRepositoryInterface", e); emailUtils.reportException(e); throw e; } @@ -442,14 +547,48 @@ public class RepositoryServiceImpl implements RepositoryService { repository.setId("openaire____::issn" + repository.getIssn()); repository.setNamespacePrefix("issn" + repository.getIssn()); this.storeRepository(repository, SecurityContextHolder.getContext().getAuthentication()); - }else if (datatype.equals("aggregator")) { + } else if (datatype.equals("aggregator")) { repository.setId("openaire____::" + com.unboundid.util.Base64.encode(repository.getOfficialName())); - repository.setNamespacePrefix(DigestUtils.md5Hex(repository.getOfficialName()).substring(0,12)); + repository.setNamespacePrefix(DigestUtils.md5Hex(repository.getOfficialName()).substring(0, 12)); this.storeRepository(repository, SecurityContextHolder.getContext().getAuthentication()); - }else { + } else { this.latentUpdate(repository, SecurityContextHolder.getContext().getAuthentication()); } + // TODO: move the following code elsewhere (creation and assignment of role to user) ?? + // Create new role + String newRoleName = roleMappingService.getRoleIdByRepoId(repository.getId()); + Role newRole = new Role(newRoleName, repository.getOfficialName()); + Integer couId = null; + try { + 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) { + LOGGER.error(String.format("Could not create role '%s'", newRoleName), e); + throw e; + } + + // Assign new role to the user that created it + Integer coPersonId = registryCalls.getCoPersonIdByIdentifier(); + if (couId != null) { + Integer role = registryCalls.getRoleId(coPersonId, couId); + try { + registryCalls.assignMemberRole(coPersonId, couId, role); + + // Add role to current user authorities + authoritiesUpdater.addRole(roleMappingService.convertRepoIdToAuthority(repository.getId())); + } catch (Exception e) { + LOGGER.debug("Exception on assign role to user during add repository", e); + throw e; + } + + } + + return repository; } @@ -465,17 +604,17 @@ public class RepositoryServiceImpl implements RepositoryService { LOGGER.debug("JSON to add(update) -> " + json_repository); HttpEntity httpEntity = new HttpEntity(json_repository, httpHeaders); - ResponseEntity responseEntity = restTemplate.exchange(uriComponents.toUri(),HttpMethod.POST, httpEntity, ResponseEntity.class); + ResponseEntity responseEntity = restTemplate.exchange(uriComponents.toUri(), HttpMethod.POST, httpEntity, ResponseEntity.class); if (responseEntity.getStatusCode().equals(HttpStatus.OK)) { - emailUtils.sendUserRegistrationEmail(repository, authentication); - emailUtils.sendAdminRegistrationEmail(repository, authentication); +// emailUtils.sendUserRegistrationEmail(repository, authentication); +// emailUtils.sendAdminRegistrationEmail(repository, authentication); } else LOGGER.debug(responseEntity.getBody().toString()); return repository; } catch (Exception e) { - LOGGER.debug("Exception on updateRepository" , e); + LOGGER.debug("Exception on updateRepository", e); emailUtils.reportException(e); throw e; } @@ -484,7 +623,7 @@ public class RepositoryServiceImpl implements RepositoryService { } @Override - public Repository updateRepository(Repository repository,Authentication authentication) throws Exception { + public Repository updateRepository(Repository repository, Authentication authentication) throws Exception { UriComponents uriComponents = UriComponentsBuilder .fromHttpUrl(baseAddress + "/ds/update/") .build() @@ -496,7 +635,7 @@ public class RepositoryServiceImpl implements RepositoryService { LOGGER.debug("JSON to update -> " + json_repository); HttpEntity httpEntity = new HttpEntity(json_repository, httpHeaders); - ResponseEntity responseEntity = restTemplate.exchange(uriComponents.toUri(),HttpMethod.POST, httpEntity + ResponseEntity responseEntity = restTemplate.exchange(uriComponents.toUri(), HttpMethod.POST, httpEntity , ResponseEntity.class); if (responseEntity.getStatusCode().equals(HttpStatus.OK)) { @@ -507,7 +646,7 @@ public class RepositoryServiceImpl implements RepositoryService { return repository; } catch (Exception e) { - LOGGER.debug("Exception on updateRepository" , e); + LOGGER.debug("Exception on updateRepository", e); emailUtils.reportException(e); throw e; } @@ -526,10 +665,10 @@ public class RepositoryServiceImpl implements RepositoryService { .build() .encode(); String json_repository = Converter.repositoryObjectToJson(repository); - HttpEntity httpEntity = new HttpEntity (json_repository,httpHeaders); - ResponseEntity responseEntity = restTemplate.exchange(uriComponents.toUri(),HttpMethod.POST, httpEntity, ResponseEntity.class); + HttpEntity httpEntity = new HttpEntity(json_repository, httpHeaders); + ResponseEntity responseEntity = restTemplate.exchange(uriComponents.toUri(), HttpMethod.POST, httpEntity, ResponseEntity.class); - if(responseEntity.getStatusCode().equals(HttpStatus.OK)) { + if (responseEntity.getStatusCode().equals(HttpStatus.OK)) { emailUtils.sendUserRegistrationEmail(repository, authentication); emailUtils.sendAdminRegistrationEmail(repository, authentication); } else { @@ -538,8 +677,8 @@ public class RepositoryServiceImpl implements RepositoryService { } @Override - public void deleteRepositoryInterface(String id , - String registeredBy){ + public void deleteRepositoryInterface(String id, + String registeredBy) { UriComponents uriComponents = UriComponentsBuilder .fromHttpUrl(baseAddress + "/ds/api/") .path("/{id}") @@ -555,17 +694,17 @@ public class RepositoryServiceImpl implements RepositoryService { String comment, RepositoryInterface repositoryInterface) throws Exception { try { Repository e = this.getRepositoryById(repoId); - repositoryInterface = createRepositoryInterface(e,repositoryInterface,datatype); - String json_interface = Converter.repositoryInterfaceObjectToJson(e,repositoryInterface); + repositoryInterface = createRepositoryInterface(e, repositoryInterface, datatype); + String json_interface = Converter.repositoryInterfaceObjectToJson(e, repositoryInterface); UriComponents uriComponents = UriComponentsBuilder .fromHttpUrl(baseAddress + "/ds/api/add/") .build() .encode(); - HttpEntity httpEntity = new HttpEntity <> (json_interface,httpHeaders); + HttpEntity httpEntity = new HttpEntity<>(json_interface, httpHeaders); - restTemplate.postForObject(uriComponents.toUri(),httpEntity, String.class); + restTemplate.postForObject(uriComponents.toUri(), httpEntity, String.class); emailUtils.sendAdminRegisterInterfaceEmail(e, comment, repositoryInterface, SecurityContextHolder.getContext().getAuthentication()); emailUtils.sendUserRegisterInterfaceEmail(e, comment, repositoryInterface, SecurityContextHolder.getContext().getAuthentication()); @@ -575,7 +714,7 @@ public class RepositoryServiceImpl implements RepositoryService { return repositoryInterface; } catch (Exception e) { - LOGGER.error("Exception on addRepositoryInterface" , e); + LOGGER.error("Exception on addRepositoryInterface", e); emailUtils.reportException(e); throw e; } @@ -586,14 +725,19 @@ public class RepositoryServiceImpl implements RepositoryService { String registeredBy, String comment, RepositoryInterface repositoryInterface) throws Exception { - this.updateBaseUrl(repoId,repositoryInterface.getId(),repositoryInterface.getBaseUrl()); - this.updateCompliance(repoId,repositoryInterface.getId(),repositoryInterface.getCompliance()); - this.updateValidationSet(repoId,repositoryInterface.getId(),repositoryInterface.getAccessSet()); + this.updateBaseUrl(repoId, repositoryInterface.getId(), repositoryInterface.getBaseUrl()); + this.updateCompliance(repoId, repositoryInterface.getId(), repositoryInterface.getCompliance()); + this.updateValidationSet(repoId, repositoryInterface.getId(), repositoryInterface.getAccessSet()); - Repository e = this.getRepositoryById(repoId); - emailUtils.sendAdminUpdateInterfaceEmail(e, comment, repositoryInterface, SecurityContextHolder.getContext().getAuthentication()); - emailUtils.sendUserUpdateInterfaceEmail(e, comment, repositoryInterface, SecurityContextHolder.getContext().getAuthentication()); - submitInterfaceValidation(getRepositoryById(repoId),registeredBy,repositoryInterface,true); + Repository repository = this.getRepositoryById(repoId); + try { + emailUtils.sendAdminUpdateInterfaceEmail(repository, comment, repositoryInterface, SecurityContextHolder.getContext().getAuthentication()); + emailUtils.sendUserUpdateInterfaceEmail(repository, comment, repositoryInterface, SecurityContextHolder.getContext().getAuthentication()); + } catch (Exception e) { + LOGGER.warn("Could not send emails", e); + } + + submitInterfaceValidation(getRepositoryById(repoId), registeredBy, repositoryInterface, true); return repositoryInterface; } @@ -665,25 +809,25 @@ public class RepositoryServiceImpl implements RepositoryService { @Override public List getTimezones() { - List timezones = Converter.readFile("timezones.txt"); + List timezones = Converter.readFile("timezones.txt"); return Converter.toTimezones(timezones); } @Override public List getUrlsOfUserRepos(String userEmail, String page, - String size){ + String size) { UriComponents uriComponents = UriComponentsBuilder .fromHttpUrl(baseAddress + "/api/baseurl/") .path("/{page}/{size}") - .build().expand(page,size).encode(); + .build().expand(page, size).encode(); - try{ + try { RequestFilter requestFilter = new RequestFilter(); requestFilter.setRegisteredby(userEmail); - return Arrays.asList(restTemplate.postForObject(uriComponents.toUri(),requestFilter, String[].class)); - }catch (Exception e){ - LOGGER.debug("Exception on addRepositoryInterface" , e); + return Arrays.asList(restTemplate.postForObject(uriComponents.toUri(), requestFilter, String[].class)); + } catch (Exception e) { + LOGGER.debug("Exception on addRepositoryInterface", e); emailUtils.reportException(e); throw e; } @@ -723,7 +867,7 @@ public class RepositoryServiceImpl implements RepositoryService { @Override - public Map getCompatibilityClasses(String mode) { + public Map getCompatibilityClasses(String mode) { LOGGER.debug("Getting compatibility classes for mode: " + mode); Map retMap = new HashMap(); @@ -752,7 +896,7 @@ public class RepositoryServiceImpl implements RepositoryService { } @Override - public Map getDatasourceClasses(String mode) { + public Map getDatasourceClasses(String mode) { LOGGER.debug("Getting datasource classes for mode: " + mode); @@ -773,16 +917,16 @@ public class RepositoryServiceImpl implements RepositoryService { retMap.put(entry.getKey(), entry.getValue()); } } - return filterResults(retMap,mode); + return filterResults(retMap, mode); } - private Map filterResults(Map map,String mode) { + private Map filterResults(Map map, String mode) { - HashMap filteredMap = new HashMap<>(); - for(String key:map.keySet()) - if(dataSourceClass.get(mode).contains(key)) - filteredMap.put(key,map.get(key)); + HashMap filteredMap = new HashMap<>(); + for (String key : map.keySet()) + if (dataSourceClass.get(mode).contains(key)) + filteredMap.put(key, map.get(key)); return filteredMap; } @@ -810,23 +954,23 @@ public class RepositoryServiceImpl implements RepositoryService { @Override public Map getListLatestUpdate(String mode) throws JSONException { - if(mode.equals("opendoar")) - return Collections.singletonMap("lastCollectionDate", getRepositoryInterface("openaire____::"+mode).get(0).getLastCollectionDate()); + if (mode.equals("opendoar")) + return Collections.singletonMap("lastCollectionDate", getRepositoryInterface("openaire____::" + mode).get(0).getLastCollectionDate()); else /* - * first api of re3data has null value on collection date - * */ - return Collections.singletonMap("lastCollectionDate", getRepositoryInterface("openaire____::"+mode).get(1).getLastCollectionDate()); + * first api of re3data has null value on collection date + * */ + return Collections.singletonMap("lastCollectionDate", getRepositoryInterface("openaire____::" + mode).get(1).getLastCollectionDate()); } private void updateValidationSet(String repositoryId, String repositoryInterfaceId, String validationSet) throws Exception { UriComponents uriComponents = UriComponentsBuilder .fromHttpUrl(baseAddress + "/ds/api/oaiset") - .queryParam("dsId",repositoryId) - .queryParam("apiId",repositoryInterfaceId) - .queryParam("oaiSet",validationSet) + .queryParam("dsId", repositoryId) + .queryParam("apiId", repositoryInterfaceId) + .queryParam("oaiSet", validationSet) .build().encode(); - restTemplate.exchange(uriComponents.toUri(),HttpMethod.POST, null, ResponseEntity.class); + restTemplate.exchange(uriComponents.toUri(), HttpMethod.POST, null, ResponseEntity.class); } @@ -834,21 +978,21 @@ public class RepositoryServiceImpl implements RepositoryService { private void updateBaseUrl(String repositoryId, String repositoryInterfaceId, String baseUrl) { UriComponents uriComponents = UriComponentsBuilder .fromHttpUrl(baseAddress + "/ds/api/baseurl") - .queryParam("dsId",repositoryId) - .queryParam("apiId",repositoryInterfaceId) - .queryParam("baseUrl",baseUrl) + .queryParam("dsId", repositoryId) + .queryParam("apiId", repositoryInterfaceId) + .queryParam("baseUrl", baseUrl) .build().encode(); - restTemplate.postForObject(uriComponents.toUri(),null,String.class); + restTemplate.postForObject(uriComponents.toUri(), null, String.class); } - private void updateCompliance(String repositoryId, String repositoryInterfaceId,String compliance) { + private void updateCompliance(String repositoryId, String repositoryInterfaceId, String compliance) { UriComponents uriComponents = UriComponentsBuilder .fromHttpUrl(baseAddress + "/ds/api/compliance") - .queryParam("dsId",repositoryId) - .queryParam("apiId",repositoryInterfaceId) - .queryParam("compliance",compliance) + .queryParam("dsId", repositoryId) + .queryParam("apiId", repositoryInterfaceId) + .queryParam("compliance", compliance) .build().encode(); - restTemplate.postForObject(uriComponents.toUri(),null,String.class); + restTemplate.postForObject(uriComponents.toUri(), null, String.class); } private MetricsNumbers getMetricsNumbers(String openAIREID) throws BrokerException { @@ -869,7 +1013,7 @@ public class RepositoryServiceImpl implements RepositoryService { new ParameterizedTypeReference() { }); } catch (RestClientException e) { - LOGGER.debug("Exception on getMetricsNumbers" , e); + LOGGER.debug("Exception on getMetricsNumbers", e); emailUtils.reportException(e); throw e; } @@ -886,39 +1030,58 @@ public class RepositoryServiceImpl implements RepositoryService { return null; } - private UriComponents searchDatasource(String page,String size){ + private UriComponents searchDatasource(String page, String size) { return UriComponentsBuilder .fromHttpUrl(baseAddress + "/ds/search/") .path("/{page}/{size}/") - .queryParam("requestSortBy","officialname") - .queryParam("order","ASCENDING") + .queryParam("requestSortBy", "officialname") + .queryParam("order", "ASCENDING") .build().expand(page, size).encode(); } - private UriComponents searchSnipperDatasource(String page,String size){ + private UriComponents searchSnipperDatasource(String page, String size) { return UriComponentsBuilder .fromHttpUrl(baseAddress + "/ds/searchsnippet/") .path("/{page}/{size}/") - .queryParam("requestSortBy","officialname") - .queryParam("order","ASCENDING") + .queryParam("requestSortBy", "officialname") + .queryParam("order", "ASCENDING") .build().expand(page, size).encode(); } - private UriComponents searchRegisteredDatasource(String requestSortBy, String order, String page,String size){ + private UriComponents searchRegisteredDatasource(String requestSortBy, String order, String page, String size) { return UriComponentsBuilder .fromHttpUrl(baseAddress + "/ds/searchregistered/") .path("/{page}/{size}/") - .queryParam("requestSortBy",requestSortBy) - .queryParam("order",order) + .queryParam("requestSortBy", requestSortBy) + .queryParam("order", order) .build().expand(page, size).encode(); } - private String getRepositoryType(String typology){ + private String getRepositoryType(String typology) { return invertedDataSourceClass.get(typology); } + private List getRoleIdsFromUserRoles(String userEmail) { + Integer coPersonId = registryCalls.getCoPersonIdByEmail(userEmail); + JsonArray roles; + ArrayList roleIds = new ArrayList<>(); + ArrayList couIds = new ArrayList<>(); + if (coPersonId != null) { + roles = registryCalls.getRolesWithStatus(coPersonId, AaiRegistryService.RoleStatus.ACTIVE); + for (JsonElement role : roles) { + JsonObject object = role.getAsJsonObject(); + if (object.get("CouId") == null) { + continue; + } + couIds.add(object.get("CouId").getAsInt()); + } + roleIds.addAll(registryCalls.getCouNames(couIds).values()); + + } + return roleIds; + } } diff --git a/src/main/java/eu/dnetlib/repo/manager/service/SushiliteServiceImpl.java b/src/main/java/eu/dnetlib/repo/manager/service/SushiliteServiceImpl.java index 3344a6e..a99a198 100644 --- a/src/main/java/eu/dnetlib/repo/manager/service/SushiliteServiceImpl.java +++ b/src/main/java/eu/dnetlib/repo/manager/service/SushiliteServiceImpl.java @@ -31,7 +31,7 @@ public class SushiliteServiceImpl implements SushiliteService { @Override - @PreAuthorize("hasRole('ROLE_USER')") + @PreAuthorize("hasAuthority('REGISTERED_USER')") public ReportResponseWrapper getReportResults(String page, String pageSize, String Report, diff --git a/src/main/java/eu/dnetlib/repo/manager/service/ValidatorServiceImpl.java b/src/main/java/eu/dnetlib/repo/manager/service/ValidatorServiceImpl.java index 57168b4..f929437 100644 --- a/src/main/java/eu/dnetlib/repo/manager/service/ValidatorServiceImpl.java +++ b/src/main/java/eu/dnetlib/repo/manager/service/ValidatorServiceImpl.java @@ -127,7 +127,7 @@ public class ValidatorServiceImpl implements ValidatorService { } @Override - @PreAuthorize("hasRole('ROLE_USER') and #jobForValidation.userEmail == authentication.userInfo.email") + @PreAuthorize("hasAuthority('REGISTERED_USER') and #jobForValidation.userEmail == authentication.userInfo.email") public JobForValidation submitJobForValidation(JobForValidation jobForValidation) throws ValidatorServiceException { LOGGER.debug("Submit job for validation with id : " + jobForValidation.getDatasourceId()); try { @@ -155,7 +155,7 @@ public class ValidatorServiceImpl implements ValidatorService { } @Override - @PreAuthorize("hasRole('ROLE_USER') and #email == authentication.userInfo.email") + @PreAuthorize("hasAuthority('REGISTERED_USER') and #email == authentication.userInfo.email") public ResponseEntity reSubmitJobForValidation(String email, String jobId) throws JSONException, ValidatorServiceException { LOGGER.debug("Resubmit validation job with id : " + jobId); @@ -242,7 +242,7 @@ public class ValidatorServiceImpl implements ValidatorService { } @Override - @PreAuthorize("hasRole('ROLE_USER')") + @PreAuthorize("hasAuthority('REGISTERED_USER')") public List getStoredJobsNew(String user, String jobType, String offset, diff --git a/src/main/java/eu/dnetlib/repo/manager/service/aai/registry/AaiRegistryService.java b/src/main/java/eu/dnetlib/repo/manager/service/aai/registry/AaiRegistryService.java new file mode 100644 index 0000000..6fe4888 --- /dev/null +++ b/src/main/java/eu/dnetlib/repo/manager/service/aai/registry/AaiRegistryService.java @@ -0,0 +1,285 @@ +package eu.dnetlib.repo.manager.service.aai.registry; + +import com.google.gson.JsonArray; +import com.google.gson.JsonObject; +import eu.dnetlib.repo.manager.domain.dto.Role; +import eu.dnetlib.repo.manager.domain.dto.User; + +import java.util.List; +import java.util.Map; + +public interface AaiRegistryService { + + /** + * 1.1 Get CoPersonId by authenticated user's Email + * + * @return + */ + Integer getCoPersonIdByEmail(); + + /** + * 1.2 Get CoPersonId by Email + * + * @param email + * @return + */ + Integer getCoPersonIdByEmail(String email); + + /** + * 1. Get CoPersonId List by Email + * + * @param email + * @return + */ + List getCoPersonIdsByEmail(String email); + + /** + * 2. Get CoPersonId by AAI identifier + * + * @return + */ + Integer getCoPersonIdByIdentifier(); + + /** + * 3.1 Get OpenAIRE cous with a specific name(or substring) + * + * @param name + * @return + */ + JsonArray getCous(String name); + + /** + * 3.2 Get all OpenAIRE cous + * + * @return + */ + JsonArray getCous(); + + /** + * 4.1 Get a couId by name + * + * @param name + * @return + */ + Integer getCouId(String name); + + /** + * 4.2 Get a couId by type.id with/without mapping type + * + * @param type + * @param id + * @return + */ + Integer getCouId(String type, String id, boolean communityMap); + + /** + * 4.3 Get a couId by type.id with mapping type + * + * @param type + * @param id + * @return + */ + Integer getCouId(String type, String id); + + /** + * 5. Get User non admin roles + * + * @param coPersonId + * @return + */ + JsonArray getRoles(Integer coPersonId); + + /** + * 5.2 Get User non admin active roles + * + * @param coPersonId + * @return + */ + JsonArray getRolesWithStatus(Integer coPersonId, RoleStatus status); + + /** + * 6. Get Role id of User base on couId. + * + * @param coPersonId + * @param couId + * @return + */ + Integer getRoleId(Integer coPersonId, Integer couId); + + /** + * 7. Get User Groups + * + * @param coPersonId + * @return + */ + JsonArray getUserGroups(Integer coPersonId); + + /** + * 8. Get User Admin Group of a Cou + * + * @param coPersonId + * @param couId + * @return + */ + JsonObject getUserAdminGroup(Integer coPersonId, Integer couId); + + /** + * 9. Get Groups of a Cou + * + * @param couId + * @return + */ + JsonArray getCouGroups(Integer couId); + + /** + * 10. Get Admin Group of a Cou + * + * @param couId + * @return + */ + JsonObject getCouAdminGroup(Integer couId); + + /** + * 11. Get users of a group + * + * @param coGroupId + * @return + */ + JsonArray getGroupMembers(Integer coGroupId); + + + /** + * 12. Get Users' email of a Cou + * + * @param couId + * @param admin + * @return + */ + JsonArray getUserEmailByCouId(Integer couId, boolean admin); + + /** + * 12.2 Get All Users that have a specific role // TODO: Keep or delete + * + * @param couId + * @return + */ + JsonArray getUsersByCouId(Integer couId); + + /** + * 13. Get Users' names of a Cou + * + * @param couId + * @param admin + * @return + */ + JsonArray getUserNamesByCouId(Integer couId, boolean admin); + + /** + * 14. Get Users' identifiers of a Cou + * + * @param couId + * @param admin + * @return + */ + JsonArray getUserIdByCouId(Integer couId, boolean admin); + + /** + * 15. Assign a member role to a User + * + * @param coPersonId + * @param couId + * @param id + */ + void assignMemberRole(Integer coPersonId, Integer couId, Integer id); + + /** + * 16. Remove a member role from a User + * + * @param coPersonId + * @param couId + * @param id + */ + void removeMemberRole(Integer coPersonId, Integer couId, Integer id); + + /** + * 17. Create a new role + * + * @param role + * @return + */ + Integer createRole(Role role); + + /** + * 18. Get User's email + * + * @param coPersonId + * @return + */ + String getUserEmail(Integer coPersonId); + + /** + * 19. Get User's names + * + * @param coPersonId + * @return + */ + String getUserNames(Integer coPersonId); + + /** + * 20. Get User's identifier + * + * @param coPersonId + * @return + */ + String getUserId(Integer coPersonId); + + /** + * 21. Assign an admin role to a User + * + * @param coPersonId + * @param couId + */ + void assignAdminRole(Integer coPersonId, Integer couId); + + /** + * 22. Remove an admin role from a User + * + * @param coPersonId + * @param couId + */ + void removeAdminRole(Integer coPersonId, Integer couId); + + /** + * 23. Get a cou Names from couIds. + * + * @param couIds + * @return + */ + Map getCouNames(List couIds); + + // TODO: add description + List getUsers(Integer couId); + + enum RoleStatus { + ACTIVE("Active"), + APPROVED("Approved"), + CONFIRMED("Confirmed"), + DECLINED("Declined"), + DELETED("Deleted"), + DENIED("Denied"), + DUPLICATE("Duplicate"), + EXPIRED("Expired"), + GRACE_PERIOD("GracePeriod"), + INVITED("Invited"), + PENDING("Pending"), + PENDING_APPROVAL("PendingApproval"), + PENDING_CONFIRMATION("PendingConfirmation"), + SUSPENDED("Suspended"); + + public final String status; + + RoleStatus(String status) { + this.status = status; + } + } +} diff --git a/src/main/java/eu/dnetlib/repo/manager/service/aai/registry/RegistryCalls.java b/src/main/java/eu/dnetlib/repo/manager/service/aai/registry/RegistryCalls.java new file mode 100644 index 0000000..bc60e87 --- /dev/null +++ b/src/main/java/eu/dnetlib/repo/manager/service/aai/registry/RegistryCalls.java @@ -0,0 +1,439 @@ +package eu.dnetlib.repo.manager.service.aai.registry; + +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import eu.dnetlib.repo.manager.domain.dto.Role; +import eu.dnetlib.repo.manager.domain.dto.User; +import eu.dnetlib.repo.manager.service.aai.registry.utils.RegistryUtils; +import eu.dnetlib.repo.manager.utils.HttpUtils; +import org.apache.log4j.Logger; +import org.mitre.openid.connect.model.OIDCAuthenticationToken; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.stereotype.Service; + +import java.net.URLEncoder; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +@Service +public class RegistryCalls implements AaiRegistryService { + + private static final Logger logger = Logger.getLogger(RegistryCalls.class); + + private final String coid; + public final HttpUtils httpUtils; + public final RegistryUtils jsonUtils; + + @Autowired + RegistryCalls(@Value("${aai.registry.coid:2}") String coid, + HttpUtils httpUtils, RegistryUtils registryUtils) { + this.coid = coid; + this.httpUtils = httpUtils; + this.jsonUtils = registryUtils; + } + + private String mapType(String type, boolean communityMap) { + if (type.equals("organization")) { + type = "institution"; + } else if (type.equals("ri") && communityMap) { + type = "community"; + } + return type; + } + + @Override + public Integer getCoPersonIdByEmail() { + try { + OIDCAuthenticationToken authentication = (OIDCAuthenticationToken) SecurityContextHolder.getContext().getAuthentication(); + String email = authentication.getUserInfo().getEmail(); + Map params = new HashMap<>(); + params.put("coid", coid); + params.put("mail", email); + JsonElement response = httpUtils.get("co_people.json", params); + return (response != null) ? response.getAsJsonObject().get("CoPeople").getAsJsonArray().get(0).getAsJsonObject().get("Id").getAsInt() : null; + } catch (Exception e) { + logger.error("Get User info: An error occurred ", e); + return null; + } + } + + @Override + public Integer getCoPersonIdByEmail(String email) { + Map params = new HashMap<>(); + params.put("coid", coid); + params.put("mail", email); + JsonElement response = httpUtils.get("co_people.json", params); + if (response != null) { + JsonArray coPeople = response.getAsJsonObject().get("CoPeople").getAsJsonArray(); + if (coPeople.size() > 0) { + return coPeople.get(0).getAsJsonObject().get("Id").getAsInt(); + } + } + return null; + } + + @Override + public List getCoPersonIdsByEmail(String email) { + List coPersonIds = new ArrayList<>(); + Map params = new HashMap<>(); + params.put("coid", coid); + params.put("mail", email); + JsonElement response = httpUtils.get("co_people.json", params); + if (response != null) { + JsonArray coPeople = response.getAsJsonObject().get("CoPeople").getAsJsonArray(); + for (int i = 0; i < coPeople.size(); i++) { + coPersonIds.add(coPeople.get(i).getAsJsonObject().get("Id").getAsInt()); + } + } + return coPersonIds; + } + + @Override + public Integer getCoPersonIdByIdentifier() { + try { + OIDCAuthenticationToken authentication = (OIDCAuthenticationToken) SecurityContextHolder.getContext().getAuthentication(); + String sub = authentication.getUserInfo().getSub(); + Map params = new HashMap<>(); + params.put("coid", coid); + params.put("search.identifier", sub); + JsonElement response = httpUtils.get("co_people.json", params); + return (response != null) ? response.getAsJsonObject().get("CoPeople").getAsJsonArray().get(0).getAsJsonObject().get("Id").getAsInt() : null; + } catch (Exception e) { + logger.error("Get User info: An error occurred ", e); + return null; + } + } + + public Integer getCoPersonIdByIdentifier(String sub) { + Map params = new HashMap<>(); + params.put("coid", coid); + params.put("search.identifier", sub); + JsonElement response = httpUtils.get("co_people.json", params); + return (response != null) ? response.getAsJsonObject().get("CoPeople").getAsJsonArray().get(0).getAsJsonObject().get("Id").getAsInt() : null; + } + + @Override + public JsonArray getCous(String name) { + Map params = new HashMap<>(); + params.put("coid", coid); + if (name != null) { + params.put("name", URLEncoder.encode(name).toLowerCase()); + } + JsonElement response = httpUtils.get("cous.json", params); + return (response != null) ? response.getAsJsonObject().get("Cous").getAsJsonArray() : new JsonArray(); + } + + @Override + public JsonArray getCous() { + return getCous(null); + } + + @Override + public Integer getCouId(String name) { + JsonArray cous = getCous(name); + for (JsonElement cou : cous) { + if (cou.getAsJsonObject().get("Name").getAsString().equalsIgnoreCase(name)) { + return cou.getAsJsonObject().get("Id").getAsInt(); + } + } + return null; + } + + @Override + public Integer getCouId(String type, String id, boolean communityMap) { + return getCouId(mapType(type, communityMap) + "." + id); + } + + @Override + public Integer getCouId(String type, String id) { + return getCouId(type, id, true); + } + + @Override + public JsonArray getRoles(Integer coPersonId) { + Map params = new HashMap<>(); + params.put("copersonid", coPersonId.toString()); + JsonElement response = httpUtils.get("co_person_roles.json", params); + return (response != null) ? response.getAsJsonObject().get("CoPersonRoles").getAsJsonArray() : new JsonArray(); + } + + @Override + public JsonArray getRolesWithStatus(Integer coPersonId, RoleStatus status) { + JsonArray roles = getRoles(coPersonId); + if (status == null) { + return roles; + } + JsonArray activeRoles = new JsonArray(); + for (JsonElement role : roles) { + if (role.getAsJsonObject().get("Status").getAsString().equalsIgnoreCase(status.toString())) { + activeRoles.add(role); + } + } + return activeRoles; + } + + @Override + public Integer getRoleId(Integer coPersonId, Integer couId) { + JsonArray roles = getRoles(coPersonId); + for (JsonElement role : roles) { + JsonObject object = role.getAsJsonObject(); + if (object.get("CouId").getAsInt() == couId && !object.get("Status").getAsString().equals("Deleted")) { + return object.get("Id").getAsInt(); + } + } + return null; + } + + @Override + public JsonArray getUserGroups(Integer coPersonId) { + Map params = new HashMap<>(); + params.put("copersonid", coPersonId.toString()); + JsonElement response = httpUtils.get("co_groups.json", params); + return (response != null) ? response.getAsJsonObject().get("CoGroups").getAsJsonArray() : new JsonArray(); + } + + @Override + public JsonObject getUserAdminGroup(Integer coPersonId, Integer couId) { + Map params = new HashMap<>(); + params.put("copersonid", coPersonId.toString()); + JsonElement response = httpUtils.get("co_groups.json", params); + JsonArray roles = (response != null) ? response.getAsJsonObject().get("CoGroups").getAsJsonArray() : new JsonArray(); + for (JsonElement role : roles) { + JsonObject object = role.getAsJsonObject(); + if (object.get("CouId") != null && object.get("CouId").getAsInt() == couId) { + if (object.get("Name").getAsString().contains("admins")) { + return object; + } + } + } + return null; + } + + @Override + public JsonArray getCouGroups(Integer couId) { + Map params = new HashMap<>(); + params.put("coid", coid); + params.put("couid", couId.toString()); + JsonElement response = httpUtils.get("co_groups.json", params); + return (response != null) ? response.getAsJsonObject().get("CoGroups").getAsJsonArray() : new JsonArray(); + } + + @Override + public JsonObject getCouAdminGroup(Integer couId) { + JsonArray groups = getCouGroups(couId); + for (JsonElement group : groups) { + if (group.getAsJsonObject().get("Name").getAsString().contains("admins")) { + return group.getAsJsonObject(); + } + } + return null; + } + + @Override + public JsonArray getGroupMembers(Integer coGroupId) { + Map params = new HashMap<>(); + params.put("cogroupid", coGroupId.toString()); + JsonElement response = httpUtils.get("co_group_members.json", params); + return (response != null) ? response.getAsJsonObject().get("CoGroupMembers").getAsJsonArray() : new JsonArray(); + } + + + @Override + public JsonArray getUserEmailByCouId(Integer couId, boolean admin) { + Map params = new HashMap<>(); + if (couId == null) { + throw new IllegalArgumentException("Provided 'couId' is null"); + } + params.put("couid", couId.toString()); + if (admin) { + params.put("admin", "true"); + } + JsonElement response = httpUtils.get("email_addresses.json", params); + JsonArray infos = (response != null) ? response.getAsJsonObject().get("EmailAddresses").getAsJsonArray() : new JsonArray(); + JsonArray emails = new JsonArray(); + infos.forEach(info -> { + JsonObject user = new JsonObject(); + boolean add = true; + String email = info.getAsJsonObject().get("Mail").getAsString(); + for (JsonElement element : emails) { + if (element.getAsJsonObject().get("email").getAsString().equals(email)) { + add = false; + } + } + if (add) { + user.addProperty("email", email); + user.addProperty("memberSince", info.getAsJsonObject().get("Created").getAsString()); + emails.add(user); + } + }); + return emails; + } + + @Override + public JsonArray getUsersByCouId(Integer couId) { + Map params = new HashMap<>(); + params.put("couid", couId.toString()); + JsonElement response = httpUtils.get("co_person_roles.json", params); + JsonArray infos = (response != null) ? response.getAsJsonObject().get("CoPersonRoles").getAsJsonArray() : new JsonArray(); +// JsonArray users = new JsonArray(); +// infos.forEach(info -> { +// JsonObject user = new JsonObject(); +// user.addProperty("email", info.getAsJsonObject().get("Mail").getAsString()); +// user.addProperty("memberSince", info.getAsJsonObject().get("Created").getAsString()); +// emails.add(user); +// }); + return infos; + } + + @Override + public List getUsers(Integer couId) { + List users = new ArrayList<>(); + JsonArray infos = getUserEmailByCouId(couId, false); + + infos.forEach(info -> { + User user = new User(); + user.setEmail(info.getAsJsonObject().get("email").getAsString()); + + users.add(user); + }); + return users; + } + + @Override + public JsonArray getUserNamesByCouId(Integer couId, boolean admin) { + Map params = new HashMap<>(); + params.put("couid", couId.toString()); + if (admin) { + params.put("admin", "true"); + } + JsonElement response = httpUtils.get("names.json", params); + JsonArray infos = (response != null) ? response.getAsJsonObject().get("Names").getAsJsonArray() : new JsonArray(); + JsonArray names = new JsonArray(); + infos.forEach(info -> { + JsonObject user = new JsonObject(); + user.addProperty("name", info.getAsJsonObject().get("Given").getAsString() + " " + info.getAsJsonObject().get("Family").getAsString()); + user.addProperty("memberSince", info.getAsJsonObject().get("Created").getAsString()); + names.add(user); + }); + return names; + } + + @Override + public JsonArray getUserIdByCouId(Integer couId, boolean admin) { + Map params = new HashMap<>(); + params.put("couid", couId.toString()); + if (admin) { + params.put("admin", "true"); + } + JsonElement response = httpUtils.get("identifiers.json", params); + JsonArray infos = (response != null) ? response.getAsJsonObject().get("Identifiers").getAsJsonArray() : new JsonArray(); + JsonArray emails = new JsonArray(); + infos.forEach(info -> { + JsonObject user = new JsonObject(); + user.addProperty("id", info.getAsJsonObject().get("Identifier").getAsString()); + user.addProperty("memberSince", info.getAsJsonObject().get("Created").getAsString()); + emails.add(user); + }); + return emails; + } + + @Override + public void assignMemberRole(Integer coPersonId, Integer couId, Integer id) { + if (id != null) { + httpUtils.put("co_person_roles/" + id.toString() + ".json", jsonUtils.coPersonRoles(coPersonId, couId, "Active")); + } else { + httpUtils.post("co_person_roles.json", jsonUtils.coPersonRoles(coPersonId, couId, "Active")); + } + } + + @Override + public void removeMemberRole(Integer coPersonId, Integer couId, Integer id) { + if (id != null) { + httpUtils.put("co_person_roles/" + id.toString() + ".json", jsonUtils.coPersonRoles(coPersonId, couId, "Deleted")); + } + } + + @Override + public Integer createRole(Role role) { + JsonElement element = httpUtils.post("cous.json", jsonUtils.createNewCou(role)); + return element.getAsJsonObject().get("Id").getAsInt(); + } + + @Override + public String getUserEmail(Integer coPersonId) { + Map params = new HashMap<>(); + params.put("copersonid", coPersonId.toString()); + JsonElement response = httpUtils.get("email_addresses.json", params); + JsonObject info = (response != null) ? response.getAsJsonObject().get("EmailAddresses").getAsJsonArray().get(0).getAsJsonObject() : null; + return (info != null) ? info.getAsJsonObject().get("Mail").getAsString() : null; + } + + @Override + public String getUserNames(Integer coPersonId) { + Map params = new HashMap<>(); + params.put("copersonid", coPersonId.toString()); + JsonElement response = httpUtils.get("names.json", params); + JsonObject info = (response != null) ? response.getAsJsonObject().get("Names").getAsJsonArray().get(0).getAsJsonObject() : null; + return (info != null) ? info.getAsJsonObject().get("Given").getAsString() + " " + info.getAsJsonObject().get("Family").getAsString() : null; + } + + @Override + public String getUserId(Integer coPersonId) { + Map params = new HashMap<>(); + params.put("copersonid", coPersonId.toString()); + JsonElement response = httpUtils.get("identifiers.json", params); + JsonObject info = (response != null) ? response.getAsJsonObject().get("Identifiers").getAsJsonArray().get(0).getAsJsonObject() : null; + return (info != null) ? info.getAsJsonObject().get("Identifier").getAsString() : null; + } + + @Override + public void assignAdminRole(Integer coPersonId, Integer couId) { + JsonObject group = getCouAdminGroup(couId); + if (group != null) { + httpUtils.post("co_group_members.json", jsonUtils.coGroupMembers(group.get("Id").getAsInt(), coPersonId, true)); + } + } + + @Override + public void removeAdminRole(Integer coPersonId, Integer couId) { + JsonObject adminGroup = this.getCouAdminGroup(couId); + JsonArray admins = this.getGroupMembers(adminGroup.get("Id").getAsInt()); + Integer id = null; + for (JsonElement admin : admins) { + if (admin.getAsJsonObject().get("Person").getAsJsonObject().get("Id").getAsInt() == coPersonId) { + id = admin.getAsJsonObject().get("Id").getAsInt(); + } + } + if (id != null) { + httpUtils.delete("co_group_members/" + id.toString() + ".json"); + } + } + + @Override + public Map getCouNames(List couIds) { + Map idNameMap = new HashMap<>(); + for (Integer id : couIds) { + idNameMap.put(id, null); + } + + JsonArray cous = getCous(); + int count = 0; + int total = couIds.size(); + for (JsonElement cou : cous) { + if (count < total) { + if (idNameMap.containsKey(cou.getAsJsonObject().get("Id").getAsInt())) { + idNameMap.put(cou.getAsJsonObject().get("Id").getAsInt(), cou.getAsJsonObject().get("Name").getAsString()); + count++; + } + } else { + break; + } + } + return idNameMap; + } +} diff --git a/src/main/java/eu/dnetlib/repo/manager/service/aai/registry/utils/RegistryUtils.java b/src/main/java/eu/dnetlib/repo/manager/service/aai/registry/utils/RegistryUtils.java new file mode 100644 index 0000000..7fe74f1 --- /dev/null +++ b/src/main/java/eu/dnetlib/repo/manager/service/aai/registry/utils/RegistryUtils.java @@ -0,0 +1,76 @@ +package eu.dnetlib.repo.manager.service.aai.registry.utils; + +import com.google.gson.JsonArray; +import com.google.gson.JsonObject; +import eu.dnetlib.repo.manager.domain.dto.Role; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +@Component +public class RegistryUtils { + + @Value("1.0") + private String version; + + @Value("2") + private String coid; + + public JsonObject coPersonRoles(Integer coPersonId, Integer couId, String status) { + JsonObject role = new JsonObject(); + JsonArray coPersonRoles = new JsonArray(); + JsonObject coPersonRole = new JsonObject(); + JsonObject person = new JsonObject(); + person.addProperty("Type", "CO"); + person.addProperty("Id", coPersonId.toString()); + coPersonRole.addProperty("Version", version); + coPersonRole.add("Person", person); + coPersonRole.addProperty("CouId", couId.toString()); + coPersonRole.addProperty("Affiliation", "member"); + coPersonRole.addProperty("Title", ""); + coPersonRole.addProperty("O", "Openaire"); + coPersonRole.addProperty("Status", status); + coPersonRole.addProperty("ValidFrom", ""); + coPersonRole.addProperty("ValidThrough", ""); + coPersonRoles.add(coPersonRole); + role.addProperty("RequestType", "CoPersonRoles"); + role.addProperty("Version", version); + role.add("CoPersonRoles", coPersonRoles); + return role; + } + + public JsonObject createNewCou(Role role) { + JsonObject cou = new JsonObject(); + JsonArray cous = new JsonArray(); + JsonObject newCou = new JsonObject(); + newCou.addProperty("Version", version); + newCou.addProperty("CoId", coid); + newCou.addProperty("Name", role.getName()); + newCou.addProperty("Description", role.getDescription()); + cous.add(newCou); + cou.addProperty("RequestType", "Cous"); + cou.addProperty("Version", version); + cou.add("Cous", cous); + return cou; + } + + public JsonObject coGroupMembers(Integer coGroupId, Integer coPersonId, boolean member) { + JsonObject coGroup = new JsonObject(); + JsonArray coGroupMembers = new JsonArray(); + JsonObject coGroupMember = new JsonObject(); + JsonObject person = new JsonObject(); + person.addProperty("Type", "CO"); + person.addProperty("Id", coPersonId.toString()); + coGroupMember.addProperty("Version", version); + coGroupMember.add("Person", person); + coGroupMember.addProperty("CoGroupId", coGroupId.toString()); + coGroupMember.addProperty("Member", member); + coGroupMember.addProperty("Owner", false); + coGroupMember.addProperty("ValidFrom", ""); + coGroupMember.addProperty("ValidThrough", ""); + coGroupMembers.add(coGroupMember); + coGroup.addProperty("RequestType", "CoGroupMembers"); + coGroup.addProperty("Version", version); + coGroup.add("CoGroupMembers", coGroupMembers); + return coGroup; + } +} diff --git a/src/main/java/eu/dnetlib/repo/manager/service/security/AaiRoleMappingService.java b/src/main/java/eu/dnetlib/repo/manager/service/security/AaiRoleMappingService.java new file mode 100644 index 0000000..de89483 --- /dev/null +++ b/src/main/java/eu/dnetlib/repo/manager/service/security/AaiRoleMappingService.java @@ -0,0 +1,120 @@ +package eu.dnetlib.repo.manager.service.security; + +import org.apache.log4j.Logger; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.stereotype.Service; + +import java.net.URLEncoder; +import java.util.Collection; +import java.util.Objects; +import java.util.stream.Collectors; + +@Service("roleMappingService") +public class AaiRoleMappingService implements RoleMappingService { + + private static final Logger logger = Logger.getLogger(AaiRoleMappingService.class); + + @Value("${aai.registry.production:true}") + private boolean production; + + + private String createRepoRoleName(String prefix, String repoId) { + return prefix + "." + repoId.replace(":", "$"); + } + + @Override + public String getRepoNameWithoutType(String fullName, String prefix) { + if (fullName != null && prefix != null && fullName.startsWith(prefix)) { + return fullName.substring(prefix.length()); + } + return null; + } + + @Override + public String getRepoIdByRoleId(String roleId) { + if (!roleActive(roleId)) { + return null; + } + return roleId.replaceFirst(".*datasource\\.", "").replace("$", ":"); + } + + @Override + public Collection getRepoIdsByRoleIds(Collection roleIds) { + return roleIds + .stream() + //.filter(this::roleActive) // implicitly executed in the next statement + .map(this::getRepoIdByRoleId) + .filter(Objects::nonNull) + .collect(Collectors.toList()); + } + + @Override + public String getRoleIdByRepoId(String repoId) { + String roleId = ""; + String prefix = (production ? "" : "beta.") + "datasource"; + if (repoId != null) { + roleId = createRepoRoleName(prefix, repoId); + return roleId; + } else { + return null; + } + + } + + @Override + public Collection getRoleIdsByRepoIds(Collection repoIds) { + return repoIds + .stream() + .map(this::getRoleIdByRepoId) + .filter(Objects::nonNull) + .collect(Collectors.toList()); + } + + @Override + public String convertAuthorityIdToRepoId(String authorityId) { + String repo = ""; + if (authorityId != null && roleActive(authorityId)) { + repo = authorityId + .replaceFirst(".*datasource\\.", "") + .replace("$", ":") + .toLowerCase(); + } + return repo; + } + + @Override + public String convertAuthorityToRepoId(GrantedAuthority authority) { + return convertAuthorityIdToRepoId(authority.toString()); + } + + @Override + public String convertRepoIdToAuthorityId(String repoId) { + StringBuilder roleBuilder = new StringBuilder(); + String role = ""; + if (repoId != null) { + roleBuilder.append(production ? "" : "beta."); + roleBuilder.append("datasource."); + roleBuilder.append(repoId.replace(":", "$")); + role = roleBuilder.toString().replace(".", "_").toUpperCase(); + } + return role; + } + + @Override + public String convertRepoIdToEncodedAuthorityId(String repoId) { + return URLEncoder.encode(convertRepoIdToAuthorityId(repoId)); + } + + @Override + public SimpleGrantedAuthority convertRepoIdToAuthority(String repoId) { + String role = convertRepoIdToEncodedAuthorityId(repoId); + return new SimpleGrantedAuthority(role); + } + + private boolean roleActive(String roleId) { + return (production && !roleId.toLowerCase().startsWith("beta.")) + || (!production && roleId.toLowerCase().startsWith("beta.")); + } +} diff --git a/src/main/java/eu/dnetlib/repo/manager/service/security/AuthoritiesMapper.java b/src/main/java/eu/dnetlib/repo/manager/service/security/AuthoritiesMapper.java new file mode 100644 index 0000000..567cca9 --- /dev/null +++ b/src/main/java/eu/dnetlib/repo/manager/service/security/AuthoritiesMapper.java @@ -0,0 +1,73 @@ +package eu.dnetlib.repo.manager.service.security; + +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import org.apache.log4j.Logger; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.authority.SimpleGrantedAuthority; + +import java.net.URLDecoder; +import java.util.*; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class AuthoritiesMapper { + + private static final Logger logger = Logger.getLogger(AuthoritiesMapper.class); + private static final String ENTITLEMENT_REGEX = "urn:geant:openaire[.]eu:group:([^:]*):?(.*)?:role=member#aai[.]openaire[.]eu"; + + private AuthoritiesMapper() { + } + + public static Collection map(JsonArray entitlements) { + HashSet authorities = new HashSet<>(); + entityRoles(entitlements, authorities); + return authorities; + } + + public static List entitlementRoles(JsonArray entitlements) { + List roles = new ArrayList<>(); + if (entitlements != null) { + for (JsonElement obj : entitlements) { + Matcher matcher = Pattern.compile(ENTITLEMENT_REGEX).matcher(obj.getAsString()); + if (matcher.find()) { + StringBuilder sb = new StringBuilder(); + if (matcher.group(1) != null && matcher.group(1).length() > 0) { + sb.append(matcher.group(1)); + } + if (matcher.group(2).length() > 0) { + sb.append(":"); + sb.append(matcher.group(2)); + } + String role = sb.toString().replace("+", " "); + roles.add(URLDecoder.decode(role)); + } + } + } + return roles; + } + + private static void entityRoles(JsonArray entitlements, Set authorities) { + if (entitlements != null) { + for (JsonElement obj : entitlements) { + Matcher matcher = Pattern.compile(ENTITLEMENT_REGEX).matcher(obj.getAsString()); + if (matcher.find()) { + StringBuilder sb = new StringBuilder(); + if (matcher.group(1) != null && matcher.group(1).length() > 0) { + sb.append(matcher.group(1).replace("+-+", "_").replaceAll("[+.]", "_").toUpperCase()); + } + if (matcher.group(2).length() > 0) { + sb.append("_"); + if (matcher.group(2).equals("admins")) { + sb.append("MANAGER"); + } else { + sb.append(matcher.group(2).toUpperCase()); + } + } + authorities.add(new SimpleGrantedAuthority(sb.toString())); + } + } + } + } + +} diff --git a/src/main/java/eu/dnetlib/repo/manager/service/security/AuthoritiesUpdater.java b/src/main/java/eu/dnetlib/repo/manager/service/security/AuthoritiesUpdater.java new file mode 100644 index 0000000..94c58ca --- /dev/null +++ b/src/main/java/eu/dnetlib/repo/manager/service/security/AuthoritiesUpdater.java @@ -0,0 +1,98 @@ +package eu.dnetlib.repo.manager.service.security; + +import org.apache.log4j.Logger; +import org.mitre.openid.connect.model.OIDCAuthenticationToken; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.GrantedAuthority; +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.session.ExpiringSession; +import org.springframework.session.FindByIndexNameSessionRepository; +import org.springframework.stereotype.Service; + +import java.util.Collection; +import java.util.HashSet; +import java.util.Map; + + +@Service +public class AuthoritiesUpdater extends HttpSessionSecurityContextRepository { + + private static final Logger logger = Logger.getLogger(AuthoritiesUpdater.class); + + @Autowired + FindByIndexNameSessionRepository sessions; + + public void update(String email, Collection authorities) { + if (sessions != null) { + Map map = sessions. + findByIndexNameAndIndexValue(FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME, email); + if (map != null) { + logger.debug(map.values().toArray().length); + for (ExpiringSession session : map.values()) { + logger.debug(session.getId()); + if (!session.isExpired()) { + SecurityContext securityContext = session.getAttribute(SPRING_SECURITY_CONTEXT_KEY); + Authentication authentication = securityContext.getAuthentication(); + if (authentication instanceof OIDCAuthenticationToken) { + OIDCAuthenticationToken authOIDC = (OIDCAuthenticationToken) authentication; + logger.debug(authorities); + securityContext.setAuthentication(new OIDCAuthenticationToken(authOIDC.getSub(), authOIDC.getIssuer(), + authOIDC.getUserInfo(), authorities, authOIDC.getIdToken(), + authOIDC.getAccessTokenValue(), authOIDC.getRefreshTokenValue())); + logger.debug("Update authorities"); + session.setAttribute(SPRING_SECURITY_CONTEXT_KEY, securityContext); + sessions.save(session); + } + } + } + } + } + } + + public void update(String email, Update update) { + Collection authorities = update.authorities(SecurityContextHolder.getContext().getAuthentication().getAuthorities()); + this.update(email, authorities); + } + + public void addRole(String email, GrantedAuthority role) { + this.update(email, old -> { + HashSet authorities = new HashSet<>(old); + authorities.add(role); + return authorities; + }); + } + + public void addRole(GrantedAuthority role) { + Authentication auth = SecurityContextHolder.getContext().getAuthentication(); + if (auth instanceof OIDCAuthenticationToken) { + OIDCAuthenticationToken oidcAuth = (OIDCAuthenticationToken) auth; + this.addRole(oidcAuth.getUserInfo().getEmail(), role); + } else { + throw new UnauthorizedClientException("User auth is not instance of OIDCAuthenticationToken"); + } + } + + public void removeRole(String email, GrantedAuthority role) { + this.update(email, old -> { + HashSet authorities = new HashSet<>(old); + authorities.remove(role); + return authorities; + }); + } + + public void removeRole(GrantedAuthority role) { + Authentication auth = SecurityContextHolder.getContext().getAuthentication(); + if (auth instanceof OIDCAuthenticationToken) { + OIDCAuthenticationToken oidcAuth = (OIDCAuthenticationToken) auth; + this.removeRole(oidcAuth.getUserInfo().getEmail(), role); + } + } + + public interface Update { + Collection authorities(Collection old); + } +} diff --git a/src/main/java/eu/dnetlib/repo/manager/service/security/AuthorizationService.java b/src/main/java/eu/dnetlib/repo/manager/service/security/AuthorizationService.java new file mode 100644 index 0000000..d714b8f --- /dev/null +++ b/src/main/java/eu/dnetlib/repo/manager/service/security/AuthorizationService.java @@ -0,0 +1,69 @@ +package eu.dnetlib.repo.manager.service.security; + +import eu.dnetlib.repo.manager.domain.dto.User; +import eu.dnetlib.repo.manager.exception.ResourceNotFoundException; + +import java.util.Collection; +import java.util.List; + +public interface AuthorizationService { + + /** + * @param type + * @param id + * @return + */ + String member(String type, String id); //TODO: use or delete + + /** + * @param id Resource Id to check. + * @return Checks if a user is a member of a resource. + */ + boolean isMemberOf(String id); + + + /** + * Returns a list of admins of the resource. + * + * @param repoId + * @return + */ + List getAdminsOfRepo(String repoId); + + /** + * Add a user as admin to a resource. + * + * @param id Resource id + * @param email User email + * @return + * @throws ResourceNotFoundException + */ + boolean addAdmin(String id, String email) throws ResourceNotFoundException; + + /** + * Remove user from resource admins. + * + * @param id Resource id + * @param email User email + * @return + * @throws ResourceNotFoundException + */ + boolean removeAdmin(String id, String email) throws ResourceNotFoundException; + + + /** + * Returns the roles of the authenticated user. + * + * @return + */ + Collection getUserRoles(); + + /** + * Returns the roles of the user with the given email. + * + * @param email + * @return + */ + Collection getUserRoles(String email); + +} diff --git a/src/main/java/eu/dnetlib/repo/manager/service/security/AuthorizationServiceImpl.java b/src/main/java/eu/dnetlib/repo/manager/service/security/AuthorizationServiceImpl.java new file mode 100644 index 0000000..768d3ad --- /dev/null +++ b/src/main/java/eu/dnetlib/repo/manager/service/security/AuthorizationServiceImpl.java @@ -0,0 +1,149 @@ +package eu.dnetlib.repo.manager.service.security; + +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import eu.dnetlib.repo.manager.domain.dto.User; +import eu.dnetlib.repo.manager.exception.ResourceNotFoundException; +import eu.dnetlib.repo.manager.service.aai.registry.AaiRegistryService; +import org.mitre.openid.connect.model.OIDCAuthenticationToken; +import org.mitre.openid.connect.model.UserInfo; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +@Service("authorizationService") +public class AuthorizationServiceImpl implements AuthorizationService { + + public static final String SUPER_ADMINISTRATOR = "SUPER_ADMINISTRATOR"; + public static final String CONTENT_PROVIDER_DASHBOARD_ADMINISTRATOR = "CONTENT_PROVIDER_DASHBOARD_ADMINISTRATOR"; + public static final String REGISTERED_USER = "REGISTERED_USER"; + + private final RoleMappingService roleMappingService; + private final AaiRegistryService aaiRegistryService; + private final AuthoritiesUpdater authoritiesUpdater; + + @Autowired + AuthorizationServiceImpl(RoleMappingService roleMappingService, AaiRegistryService aaiRegistryService, + AuthoritiesUpdater authoritiesUpdater) { + this.roleMappingService = roleMappingService; + this.aaiRegistryService = aaiRegistryService; + this.authoritiesUpdater = authoritiesUpdater; + } + + private String mapType(String type) { + if (type.equals("datasource")) { + type = "datasource"; + } + return type; + } + + /** + * Type = DATASOURCE + */ + @Override + public String member(String type, String id) { + return mapType(type).toUpperCase() + "_" + id.toUpperCase(); + } + + @Override + public boolean isMemberOf(String repoId) { + String repoRole = roleMappingService.convertRepoIdToEncodedAuthorityId(repoId); + return SecurityContextHolder.getContext().getAuthentication().getAuthorities() + .parallelStream().anyMatch(authority -> authority.toString().equals(repoRole)); + } + + @Override + public List getAdminsOfRepo(String repoId) { + List userList = new ArrayList<>(); + + // find couId by role name + String role = roleMappingService.getRoleIdByRepoId(repoId); + Integer couId = aaiRegistryService.getCouId(role); + if (couId != null) { + JsonArray users = aaiRegistryService.getUsersByCouId(couId); + for (JsonElement jsonElement : users) { + userList.add(jsonElement.toString()); + } + } + return aaiRegistryService.getUsers(couId); + } + + + @Override + public boolean addAdmin(String id, String email) throws ResourceNotFoundException { + Integer coPersonId = aaiRegistryService.getCoPersonIdByEmail(email); + if (coPersonId != null) { + String role = roleMappingService.getRoleIdByRepoId(id); + Integer couId = aaiRegistryService.getCouId(role); + if (couId != null) { + Integer roleId = aaiRegistryService.getRoleId(coPersonId, couId); + aaiRegistryService.assignMemberRole(coPersonId, couId, roleId); + + // Add role to user current authorities + authoritiesUpdater.addRole(email, roleMappingService.convertRepoIdToAuthority(id)); + + return true; + } else { + throw new ResourceNotFoundException("Cannot find CouId for role: " + role); + } + } else { + throw new ResourceNotFoundException("Cannot find coPersonId for user with email: " + email); + } + } + + @Override + public boolean removeAdmin(String id, String email) throws ResourceNotFoundException { + Integer coPersonId = aaiRegistryService.getCoPersonIdByEmail(email); + if (coPersonId != null) { + String role = roleMappingService.getRoleIdByRepoId(id); + Integer couId = aaiRegistryService.getCouId(role); + Integer roleId = null; + if (couId != null) { + roleId = aaiRegistryService.getRoleId(coPersonId, couId); + } + if (couId != null && roleId != null) { + aaiRegistryService.removeMemberRole(coPersonId, couId, roleId); + + // Remove role from user current authorities + authoritiesUpdater.removeRole(email, roleMappingService.convertRepoIdToAuthority(id)); + + return true; + } else { + throw new ResourceNotFoundException("Cannot find CouId for role: " + role); + } + } else { + throw new ResourceNotFoundException("Cannot find coPersonId for user with email: " + email); + } + } + + @Override + public Collection getUserRoles() { + List roles; + JsonArray entitlements; + UserInfo userInfo = ((OIDCAuthenticationToken) SecurityContextHolder.getContext().getAuthentication()).getUserInfo(); + if (userInfo.getSource().getAsJsonArray("edu_person_entitlements") != null) { + entitlements = userInfo.getSource().getAsJsonArray("edu_person_entitlements"); + } else if (userInfo.getSource().getAsJsonArray("eduperson_entitlement") != null) { + entitlements = userInfo.getSource().getAsJsonArray("eduperson_entitlement"); + } else { + entitlements = new JsonArray(); + } + roles = AuthoritiesMapper.entitlementRoles(entitlements); + return roles; + } + + @Override + public Collection getUserRoles(String email) { + int coPersonId = aaiRegistryService.getCoPersonIdByEmail(email); + List list = new ArrayList<>(); + for (JsonElement element : aaiRegistryService.getRolesWithStatus(coPersonId, AaiRegistryService.RoleStatus.ACTIVE)) { + list.add(element.getAsJsonObject().get("CouId").getAsInt()); + } + return aaiRegistryService.getCouNames(list).values(); + } + +} diff --git a/src/main/java/eu/dnetlib/repo/manager/service/security/RoleMappingService.java b/src/main/java/eu/dnetlib/repo/manager/service/security/RoleMappingService.java new file mode 100644 index 0000000..67439bf --- /dev/null +++ b/src/main/java/eu/dnetlib/repo/manager/service/security/RoleMappingService.java @@ -0,0 +1,74 @@ +package eu.dnetlib.repo.manager.service.security; + +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.authority.SimpleGrantedAuthority; + +import java.util.Collection; + +public interface RoleMappingService { + + /** + * @param fullName + * @param prefix + * @return + */ + String getRepoNameWithoutType(String fullName, String prefix); + + /** + * @param roleId Role Id + * @return Converts {@param roleId} to a repo Id. + */ + String getRepoIdByRoleId(String roleId); + + /** + * + * @param roleIds Collection of roles + * @return Converts {@param roleIds} to a repo Ids. + */ + Collection getRepoIdsByRoleIds(Collection roleIds); + + /** + * @param repoId Repository Id + * @return Converts {@param repoId} to a role Id. + */ + String getRoleIdByRepoId(String repoId); + + /** + * @param repoIds Collection of Repository Ids + * @return Converts {@param repoIds} to role Ids. + */ + Collection getRoleIdsByRepoIds(Collection repoIds); + + /** + * @param authorityId Authority Id + * @return Converts {@param authorityId} to repo Id. + */ + String convertAuthorityIdToRepoId(String authorityId); + + /** + * @param authority Granted authority + * @return Converts {@param authority} to repo Id. + */ + String convertAuthorityToRepoId(GrantedAuthority authority); + + /** + * @param repoId Repository Id + * @return + */ + String convertRepoIdToAuthorityId(String repoId); + + /** + * @param repoId Repository Id + * @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); + + /** + * @param repoId Repository Id + * @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); + +} diff --git a/src/main/java/eu/dnetlib/repo/manager/utils/Converter.java b/src/main/java/eu/dnetlib/repo/manager/utils/Converter.java index 958704f..908a486 100644 --- a/src/main/java/eu/dnetlib/repo/manager/utils/Converter.java +++ b/src/main/java/eu/dnetlib/repo/manager/utils/Converter.java @@ -12,6 +12,7 @@ import org.apache.log4j.Logger; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; +import org.springframework.stereotype.Component; import java.io.BufferedReader; import java.io.IOException; @@ -21,6 +22,7 @@ import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.*; +@Component public class Converter { private static final Logger LOGGER = Logger.getLogger(Converter.class); @@ -28,7 +30,7 @@ public class Converter { public static Repository jsonToRepositoryObject(JSONObject repositoryObject) throws JSONException { Repository repository = new Repository(); - + JSONObject datasource = repositoryObject.getJSONObject("datasource"); //if( datasource.equals(null)) @@ -37,51 +39,51 @@ public class Converter { repository.setId(datasource.get("id").toString()); repository.setOfficialName(datasource.get("officialname").toString()); - repository.setEnglishName( datasource.get("englishname").toString()); - if(repository.getEnglishName().equals("null")) + repository.setEnglishName(datasource.get("englishname").toString()); + if (repository.getEnglishName().equals("null")) repository.setEnglishName(""); repository.setWebsiteUrl(datasource.get("websiteurl").toString()); - if(repository.getWebsiteUrl().equals("null")) + if (repository.getWebsiteUrl().equals("null")) repository.setWebsiteUrl(""); repository.setLogoUrl(datasource.get("logourl").toString()); - if(repository.getLogoUrl().equals("null")) + if (repository.getLogoUrl().equals("null")) repository.setLogoUrl(""); repository.setContactEmail(datasource.get("contactemail").toString()); - if(repository.getContactEmail().equals("null")) + if (repository.getContactEmail().equals("null")) repository.setContactEmail(""); - repository.setLatitude( toDouble(datasource.get("latitude").toString())); + repository.setLatitude(toDouble(datasource.get("latitude").toString())); repository.setLongitude(toDouble(datasource.get("longitude").toString())); Double timezone = toDouble(datasource.get("timezone").toString()); - repository.setTimezone(timezone!=null?timezone:0.0); + repository.setTimezone(timezone != null ? timezone : 0.0); repository.setNamespacePrefix(datasource.get("namespaceprefix").toString()); repository.setOdLanguages(datasource.get("languages").toString()); - repository.setDateOfValidation(convertStringToDate( datasource.get("dateofvalidation").toString())); + repository.setDateOfValidation(convertStringToDate(datasource.get("dateofvalidation").toString())); /* typology -> platform * datasource class -> typology */ repository.setTypology(datasource.get("platform").toString()); - if(repository.getTypology().equals("null")) + if (repository.getTypology().equals("null")) repository.setTypology(""); repository.setDatasourceClass(datasource.get("typology").toString()); - repository.setDateOfCollection(convertStringToDate( datasource.get("dateofcollection").toString())); + repository.setDateOfCollection(convertStringToDate(datasource.get("dateofcollection").toString())); repository.setActivationId(datasource.get("activationId").toString()); repository.setDescription(datasource.get("description").toString()); - if(repository.getDescription().equals("null")) + if (repository.getDescription().equals("null")) repository.setDescription(""); repository.setIssn(datasource.get("issn").toString()); repository.setLissn(datasource.get("lissn").toString()); - if(repository.getLissn().equals("null")) + if (repository.getLissn().equals("null")) repository.setLissn(""); repository.setEissn(datasource.get("eissn").toString()); - if(repository.getEissn().equals("null")) + if (repository.getEissn().equals("null")) repository.setEissn(""); repository.setRegisteredBy(datasource.get("registeredby").toString()); @@ -94,8 +96,8 @@ public class Converter { repository.setCollectedFrom(datasource.get("collectedfrom").toString()); //TODO change organization to list - JSONArray organizations = ((JSONArray)datasource.get("organizations")); - if(organizations.length() != 0) { + JSONArray organizations = ((JSONArray) datasource.get("organizations")); + if (organizations.length() != 0) { repository.setOrganization(((JSONArray) datasource.get("organizations")).getJSONObject(0).get("legalname").toString()); String countryCode = ((JSONArray) datasource.get("organizations")).getJSONObject(0).get("country").toString(); repository.setCountryCode(countryCode); @@ -106,31 +108,31 @@ public class Converter { return repository; } - public static Date convertStringToDate(String date){ + public static Date convertStringToDate(String date) { - if(Objects.equals(date, "null")) + if (Objects.equals(date, "null")) return null; SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd"); try { return formatter.parse(date); } catch (ParseException e) { - LOGGER.error(e); + LOGGER.error(e); } return null; } - public static String convertDateToString(Date date){ + public static String convertDateToString(Date date) { - if(Objects.equals(date, null)) + if (Objects.equals(date, null)) return null; SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd"); return formatter.format(date); } - public static Double toDouble(String number){ - if(Objects.equals(number, "null")) + public static Double toDouble(String number) { + if (Objects.equals(number, "null")) return 0.0; else return Double.valueOf(number); @@ -140,12 +142,12 @@ public class Converter { List resultSet = new ArrayList<>(); JSONArray rs = json.getJSONArray("datasourceInfo"); - for(int i=0;i resultSet = new ArrayList<>(); JSONArray rs = json.getJSONArray("datasourceInfo"); - for(int i=0;i resultSet = new ArrayList<>(); JSONArray rs = json.getJSONArray("api"); - for(int i=0;i repositoryMap = new HashMap<>(); + HashMap repositoryMap = new HashMap<>(); ObjectMapper mapper = new ObjectMapper(); - repositoryMap.put("id",repository.getId()); - repositoryMap.put("openaireId",getOpenaireId(repository.getId())); - repositoryMap.put("officialname",repository.getOfficialName()); - repositoryMap.put("englishname",repository.getEnglishName()); - repositoryMap.put("websiteurl",repository.getWebsiteUrl()); - repositoryMap.put("logourl",repository.getLogoUrl()); - repositoryMap.put("contactemail",repository.getContactEmail()); - repositoryMap.put("longitude",repository.getLongitude().toString()); - repositoryMap.put("latitude",repository.getLatitude().toString()); - repositoryMap.put("timezone",repository.getTimezone()); + repositoryMap.put("id", repository.getId()); + repositoryMap.put("openaireId", getOpenaireId(repository.getId())); + repositoryMap.put("officialname", repository.getOfficialName()); + repositoryMap.put("englishname", repository.getEnglishName()); + repositoryMap.put("websiteurl", repository.getWebsiteUrl()); + repositoryMap.put("logourl", repository.getLogoUrl()); + repositoryMap.put("contactemail", repository.getContactEmail()); + repositoryMap.put("longitude", repository.getLongitude().toString()); + repositoryMap.put("latitude", repository.getLatitude().toString()); + repositoryMap.put("timezone", repository.getTimezone()); - repositoryMap.put("namespaceprefix",repository.getNamespacePrefix()!=null?repository.getNamespacePrefix():""); - repositoryMap.put("languages",repository.getOdLanguages()!=null?repository.getOdLanguages():""); + repositoryMap.put("namespaceprefix", repository.getNamespacePrefix() != null ? repository.getNamespacePrefix() : ""); + repositoryMap.put("languages", repository.getOdLanguages() != null ? repository.getOdLanguages() : ""); - repositoryMap.put("dateofcollection",repository.getDateOfCollection()!=null?convertDateToString(repository.getDateOfCollection()):""); + repositoryMap.put("dateofcollection", repository.getDateOfCollection() != null ? convertDateToString(repository.getDateOfCollection()) : ""); /* - * typology -> platform - * datasource class -> typology - * */ - repositoryMap.put("typology",repository.getDatasourceClass()); - repositoryMap.put("platform",repository.getTypology()); + * typology -> platform + * datasource class -> typology + * */ + repositoryMap.put("typology", repository.getDatasourceClass()); + repositoryMap.put("platform", repository.getTypology()); - repositoryMap.put("dateofvalidation",repository.getDateOfCollection()!=null?convertDateToString(repository.getDateOfCollection()):""); - repositoryMap.put("activationId",repository.getActivationId()!=null?repository.getActivationId():""); + repositoryMap.put("dateofvalidation", repository.getDateOfCollection() != null ? convertDateToString(repository.getDateOfCollection()) : ""); + repositoryMap.put("activationId", repository.getActivationId() != null ? repository.getActivationId() : ""); - repositoryMap.put("description",repository.getDescription()); + repositoryMap.put("description", repository.getDescription()); - repositoryMap.put("eissn",repository.getEissn()!=null?repository.getEissn():""); - repositoryMap.put("issn",repository.getIssn()!=null?repository.getIssn():""); - repositoryMap.put("lissn",repository.getLissn()!=null?repository.getLissn():""); + repositoryMap.put("eissn", repository.getEissn() != null ? repository.getEissn() : ""); + repositoryMap.put("issn", repository.getIssn() != null ? repository.getIssn() : ""); + repositoryMap.put("lissn", repository.getLissn() != null ? repository.getLissn() : ""); - repositoryMap.put("registeredby",repository.getRegisteredBy()); + repositoryMap.put("registeredby", repository.getRegisteredBy()); - repositoryMap.put("aggregator",repository.getAggregator()!=null?repository.getAggregator():""); - repositoryMap.put("collectedfrom",repository.getCollectedFrom()!=null?repository.getCollectedFrom():""); + repositoryMap.put("aggregator", repository.getAggregator() != null ? repository.getAggregator() : ""); + repositoryMap.put("collectedfrom", repository.getCollectedFrom() != null ? repository.getCollectedFrom() : ""); - repositoryMap.put("managed",repository.isRegistered()); + repositoryMap.put("managed", repository.isRegistered()); - Map organization = new HashMap<>(); - organization.put("legalname",repository.getOrganization()); - organization.put("country",repository.getCountryCode()); - organization.put("legalshortname",""); - organization.put("websiteurl",""); - organization.put("logourl",""); + Map organization = new HashMap<>(); + organization.put("legalname", repository.getOrganization()); + organization.put("country", repository.getCountryCode()); + organization.put("legalshortname", ""); + organization.put("websiteurl", ""); + organization.put("logourl", ""); List organizations = new ArrayList(); organizations.add(organization); - repositoryMap.put("organizations",organizations); + repositoryMap.put("organizations", organizations); //TODO check identitites //Map identity = new HashMap<>(); @@ -293,43 +295,43 @@ public class Converter { repositoryMap.put("identities", identities); } - repositoryMap.put("subjects",""); + repositoryMap.put("subjects", ""); return mapper.writeValueAsString(repositoryMap); } - public static String repositoryInterfaceObjectToJson(Repository repository,RepositoryInterface repositoryInterface) throws JSONException { + public static String repositoryInterfaceObjectToJson(Repository repository, RepositoryInterface repositoryInterface) throws JSONException { JSONObject jsonObject = new JSONObject(); - jsonObject.put("id",repositoryInterface.getId()); - jsonObject.put("protocol",repositoryInterface.getAccessProtocol()); - jsonObject.put("datasource",repository.getId()); - jsonObject.put("contentdescription",repositoryInterface.getContentDescription()); - jsonObject.put("typology",repositoryInterface.getTypology()); - jsonObject.put("compatibility",repositoryInterface.getDesiredCompatibilityLevel()); - jsonObject.put("compatibilityOverride",repositoryInterface.getDesiredCompatibilityLevel()); + jsonObject.put("id", repositoryInterface.getId()); + jsonObject.put("protocol", repositoryInterface.getAccessProtocol()); + jsonObject.put("datasource", repository.getId()); + jsonObject.put("contentdescription", repositoryInterface.getContentDescription()); + jsonObject.put("typology", repositoryInterface.getTypology()); + jsonObject.put("compatibility", repositoryInterface.getDesiredCompatibilityLevel()); + jsonObject.put("compatibilityOverride", repositoryInterface.getDesiredCompatibilityLevel()); - jsonObject.put("lastCollectionTotal",""); + jsonObject.put("lastCollectionTotal", ""); - jsonObject.put("lastCollectionDate",repositoryInterface.getLastCollectionDate()); - jsonObject.put("lastAggregationTotal",""); - jsonObject.put("lastAggregationDate",""); - jsonObject.put("lastDownloadTotal",""); - jsonObject.put("lastDownloadDate",""); + jsonObject.put("lastCollectionDate", repositoryInterface.getLastCollectionDate()); + jsonObject.put("lastAggregationTotal", ""); + jsonObject.put("lastAggregationDate", ""); + jsonObject.put("lastDownloadTotal", ""); + jsonObject.put("lastDownloadDate", ""); + + jsonObject.put("baseurl", repositoryInterface.getBaseUrl()); + jsonObject.put("removable", repositoryInterface.isRemovable()); - jsonObject.put("baseurl",repositoryInterface.getBaseUrl()); - jsonObject.put("removable",repositoryInterface.isRemovable()); - JSONArray apiparams = new JSONArray(); - for(String param: repositoryInterface.getAccessParams().keySet()){ + for (String param : repositoryInterface.getAccessParams().keySet()) { JSONObject jo = new JSONObject(); - jo.put("param",param); - jo.put("value",repositoryInterface.getAccessParams().get(param)); + jo.put("param", param); + jo.put("value", repositoryInterface.getAccessParams().get(param)); apiparams.put(jo); } - jsonObject.put("apiParams",apiparams); + jsonObject.put("apiParams", apiparams); // jsonObject.put("metadataIdentifierPath",repositoryInterface.getMetadataIdentifierPath()); @@ -345,7 +347,7 @@ public class Converter { //InputStream in = Converter.class.getResourceAsStream("resources/eu/dnetlib/repo/manager/service/utils/"+filename); InputStream in = Converter.class.getClass().getResourceAsStream("/eu/**/" + filename); BufferedReader br = new BufferedReader(new InputStreamReader(in)); - while((line = br.readLine()) != null) { + while ((line = br.readLine()) != null) { list.add(line.trim()); } br.close(); @@ -375,9 +377,9 @@ public class Converter { AggregationDetails aggregationDetails = new AggregationDetails(); aggregationDetails.setAggregationStage(aggregationObject.get("aggregationStage").toString()); - if(aggregationObject.has("collectionMode")) + if (aggregationObject.has("collectionMode")) aggregationDetails.setCollectionMode(aggregationObject.get("collectionMode").toString()); - if(aggregationObject.has("indexedVersion")) + if (aggregationObject.has("indexedVersion")) aggregationDetails.setIndexedVersion(Boolean.parseBoolean(aggregationObject.get("indexedVersion").toString())); aggregationDetails.setDate(convertStringToDate(aggregationObject.get("date").toString())); aggregationDetails.setNumberOfRecords(Integer.parseInt(aggregationObject.get("numberOfRecords").toString())); @@ -388,9 +390,9 @@ public class Converter { public static List toTimezones(List timezones) { List tmz = new ArrayList<>(); - for(String t : timezones){ + for (String t : timezones) { String[] s = t.split("\t"); - tmz.add(new Timezone(s[1],Double.parseDouble(s[0]))); + tmz.add(new Timezone(s[1], Double.parseDouble(s[0]))); } return tmz; } diff --git a/src/main/java/eu/dnetlib/repo/manager/utils/DatasourceManagerClient.java b/src/main/java/eu/dnetlib/repo/manager/utils/DatasourceManagerClient.java new file mode 100644 index 0000000..118dd05 --- /dev/null +++ b/src/main/java/eu/dnetlib/repo/manager/utils/DatasourceManagerClient.java @@ -0,0 +1,5 @@ +package eu.dnetlib.repo.manager.utils; + +public class DatasourceManagerClient { + // +} diff --git a/src/main/java/eu/dnetlib/repo/manager/utils/HttpUtils.java b/src/main/java/eu/dnetlib/repo/manager/utils/HttpUtils.java new file mode 100644 index 0000000..9f2912f --- /dev/null +++ b/src/main/java/eu/dnetlib/repo/manager/utils/HttpUtils.java @@ -0,0 +1,99 @@ +package eu.dnetlib.repo.manager.utils; + +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; +import org.apache.commons.codec.binary.Base64; +import org.apache.log4j.Logger; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.http.*; +import org.springframework.stereotype.Component; +import org.springframework.web.client.RestTemplate; + +import java.nio.charset.Charset; +import java.util.Map; + +@Component +public class HttpUtils { + + private static final Logger logger = Logger.getLogger(HttpUtils.class); + + @Value("${aai.registry.url}") + private String registryUrl; + + @Value("${aai.registry.authentication.username}") + private String user; + + @Value("${aai.registry.authentication.password}") + private String password; + + public JsonElement post(String path, JsonObject body) { + RestTemplate restTemplate = new RestTemplate(); + HttpHeaders headers = createHeaders(user, password); + headers.setContentType(MediaType.APPLICATION_JSON); + HttpEntity request = new HttpEntity<>(body.toString(), headers); + ResponseEntity responseEntity = restTemplate.exchange(registryUrl + path, HttpMethod.POST, request, String.class); + return getResponseEntityAsJsonElement(responseEntity); + } + + public JsonElement put(String path, JsonObject body) { + RestTemplate restTemplate = new RestTemplate(); + HttpHeaders headers = createHeaders(user, password); + headers.setContentType(MediaType.APPLICATION_JSON); + HttpEntity request = new HttpEntity<>(body.toString(), headers); + ResponseEntity responseEntity = restTemplate.exchange(registryUrl + path, HttpMethod.PUT, request, String.class); + return getResponseEntityAsJsonElement(responseEntity); + } + + public JsonElement get(String path, Map params) { + RestTemplate restTemplate = new RestTemplate(); + String url = registryUrl + path + ((params != null) ? createParams(params) : null); + ResponseEntity responseEntity = restTemplate.exchange + (url, HttpMethod.GET, new HttpEntity<>(createHeaders(user, password)), String.class); + return getResponseEntityAsJsonElement(responseEntity); + } + + public JsonElement delete(String path) { + RestTemplate restTemplate = new RestTemplate(); + String url = registryUrl + path; + ResponseEntity responseEntity = restTemplate.exchange + (url, HttpMethod.DELETE, new HttpEntity<>(createHeaders(user, password)), String.class); + return getResponseEntityAsJsonElement(responseEntity); + } + + + private String createParams(Map params) { + StringBuilder ret = new StringBuilder("?"); + int count = 0; + for (Map.Entry param : params.entrySet()) { + ret.append(param.getKey()).append("=").append(param.getValue()); + count++; + if (count != params.entrySet().size()) { + ret.append("&"); + } + } + return ret.toString(); + } + + private HttpHeaders createHeaders(String username, String password) { + return new HttpHeaders() {{ + String auth = username + ":" + password; + byte[] encodedAuth = Base64.encodeBase64( + auth.getBytes(Charset.forName("US-ASCII"))); + String authHeader = "Basic " + new String(encodedAuth); + set("Authorization", authHeader); + }}; + } + + private JsonElement getResponseEntityAsJsonElement(ResponseEntity responseEntity) { + if (responseEntity != null && responseEntity.getBody() != null) { + logger.info(responseEntity.getBody()); + try { + return new JsonParser().parse(responseEntity.getBody()); + } catch (Exception e) { + logger.warn("Could not parse response body", e); + } + } + return null; + } +} diff --git a/src/main/java/eu/dnetlib/repo/manager/utils/JsonUtils.java b/src/main/java/eu/dnetlib/repo/manager/utils/JsonUtils.java new file mode 100644 index 0000000..682ebfd --- /dev/null +++ b/src/main/java/eu/dnetlib/repo/manager/utils/JsonUtils.java @@ -0,0 +1,40 @@ +package eu.dnetlib.repo.manager.utils; + +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; + +public class JsonUtils { + + private JsonUtils() { + } + + public JsonObject createResponse(JsonElement response) { + JsonObject json = new JsonObject(); + json.add("response", response); + return json; + } + + public static JsonObject createResponse(String response) { + JsonObject json = new JsonObject(); + json.addProperty("response", response); + return json; + } + + public JsonObject createResponse(Number response) { + JsonObject json = new JsonObject(); + json.addProperty("response", response); + return json; + } + + public static JsonObject createResponse(Boolean response) { + JsonObject json = new JsonObject(); + json.addProperty("response", response); + return json; + } + + public static JsonObject createResponse(Character response) { + JsonObject json = new JsonObject(); + json.addProperty("response", response); + return json; + } +}