diff --git a/dmp-backend/web/src/main/java/eu/eudat/configurations/SecurityConfiguration.java b/dmp-backend/web/src/main/java/eu/eudat/configurations/SecurityConfiguration.java index f734459b6..bc9aa06e2 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/configurations/SecurityConfiguration.java +++ b/dmp-backend/web/src/main/java/eu/eudat/configurations/SecurityConfiguration.java @@ -59,8 +59,8 @@ public class SecurityConfiguration { .headers(httpSecurityHeadersConfigurer -> httpSecurityHeadersConfigurer.frameOptions(HeadersConfigurer.FrameOptionsConfig::disable)) .addFilterBefore(apiKeyFilter, AbstractPreAuthenticatedProcessingFilter.class) .authorizeHttpRequests(authRequest -> - authRequest.requestMatchers(buildAntPatterns(webSecurityProperties.getAllowedEndpoints())).permitAll() //TODO: Authz - .requestMatchers(buildAntPatterns(webSecurityProperties.getAuthorizedEndpoints())).permitAll()) + authRequest.requestMatchers(buildAntPatterns(webSecurityProperties.getAllowedEndpoints())).anonymous() + .requestMatchers(buildAntPatterns(webSecurityProperties.getAuthorizedEndpoints())).authenticated()) .sessionManagement( sessionManagementConfigurer-> sessionManagementConfigurer.sessionCreationPolicy(SessionCreationPolicy.NEVER)) .oauth2ResourceServer(oauth2 -> oauth2.authenticationManagerResolver(authenticationManagerResolver)); return tempHttp.build(); diff --git a/dmp-backend/web/src/main/java/eu/eudat/controllers/ContactEmail.java b/dmp-backend/web/src/main/java/eu/eudat/controllers/ContactEmail.java deleted file mode 100644 index 961f938af..000000000 --- a/dmp-backend/web/src/main/java/eu/eudat/controllers/ContactEmail.java +++ /dev/null @@ -1,60 +0,0 @@ -package eu.eudat.controllers; - -import eu.eudat.authorization.Permission; -import eu.eudat.logic.managers.ContactEmailManager; -import eu.eudat.models.data.ContactEmail.ContactEmailModel; -import eu.eudat.models.data.ContactEmail.PublicContactEmailModel; -import eu.eudat.models.data.helpers.responses.ResponseItem; -import eu.eudat.types.ApiMessageCode; -import gr.cite.commons.web.authz.service.AuthorizationService; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.*; - -import jakarta.transaction.Transactional; - -@RestController -@CrossOrigin -@RequestMapping(value = "api/contactEmail") -public class ContactEmail { - private static final Logger logger = LoggerFactory.getLogger(ContactEmail.class); - - private ContactEmailManager contactEmailManager; - private final AuthorizationService authorizationService; - - public ContactEmail(ContactEmailManager contactEmailManager, AuthorizationService authorizationService) { - this.contactEmailManager = contactEmailManager; - this.authorizationService = authorizationService; - } - - @Transactional - @RequestMapping(method = RequestMethod.POST, consumes = "application/json", produces = "application/json") - public @ResponseBody - ResponseEntity sendContactEmail(@RequestBody ContactEmailModel contactEmailModel) { - this.authorizationService.authorizeForce(Permission.AuthenticatedRole); - - try { - this.contactEmailManager.emailValidation(contactEmailModel); - this.contactEmailManager.sendContactEmail(contactEmailModel); - return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().status(ApiMessageCode.SUCCESS_MESSAGE)); - } catch (Exception ex) { - logger.error(ex.getMessage(), ex); - return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ResponseItem().status(ApiMessageCode.ERROR_MESSAGE).message(ex.getMessage())); - } - } - - @Transactional - @RequestMapping(method = RequestMethod.POST, path = "public", consumes = "application/x-www-form-urlencoded", produces = "application/json") - public @ResponseBody - ResponseEntity sendContactEmailNoAuth(@ModelAttribute PublicContactEmailModel contactEmailModel) { - try { - this.contactEmailManager.sendContactEmailNoAuth(contactEmailModel); - return ResponseEntity.status(HttpStatus.NO_CONTENT).body(new ResponseItem().status(ApiMessageCode.SUCCESS_MESSAGE)); - } catch (Exception ex) { - logger.error(ex.getMessage(), ex); - return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ResponseItem().status(ApiMessageCode.ERROR_MESSAGE).message(ex.getMessage())); - } - } -} diff --git a/dmp-backend/web/src/main/java/eu/eudat/controllers/LanguageController.java b/dmp-backend/web/src/main/java/eu/eudat/controllers/LanguageController.java deleted file mode 100644 index 69aeeef48..000000000 --- a/dmp-backend/web/src/main/java/eu/eudat/controllers/LanguageController.java +++ /dev/null @@ -1,62 +0,0 @@ -package eu.eudat.controllers; - -import eu.eudat.authorization.Permission; -import eu.eudat.models.data.helpers.responses.ResponseItem; -import eu.eudat.service.storage.StorageFileService; -import eu.eudat.types.ApiMessageCode; -import gr.cite.commons.web.authz.service.AuthorizationService; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.core.env.Environment; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpStatus; -import org.springframework.http.MediaType; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.*; - -import java.io.*; - -@RestController -@CrossOrigin -@RequestMapping(value = {"/api/language/"}) -public class LanguageController { - - private Environment environment; - private final AuthorizationService authorizationService; - private final StorageFileService storageFileService; - - @Autowired - public LanguageController(Environment environment, AuthorizationService authorizationService, StorageFileService storageFileService) { - this.environment = environment; - this.authorizationService = authorizationService; - this.storageFileService = storageFileService; - } - - @RequestMapping(value = "update/{lang}", method = RequestMethod.POST) - public @ResponseBody - ResponseEntity> updateLang(@PathVariable String lang, @RequestBody String json) throws Exception { - this.authorizationService.authorizeForce(Permission.EditLanguage); - - this.storageFileService.setLanguage(lang, lang.getBytes()); - - return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().status(ApiMessageCode.SUCCESS_MESSAGE).message("Updated").payload("Updated")); - } - - @RequestMapping(value = "{lang}", method = RequestMethod.GET) - public ResponseEntity getLanguage(@PathVariable String lang) throws IOException { - - this.authorizationService.authorizeForce(Permission.BrowseLanguage); - - File file = this.storageFileService.getLanguageFileName(lang); - byte[] content = this.storageFileService.getLanguage(lang); - - HttpHeaders responseHeaders = new HttpHeaders(); - responseHeaders.setContentLength(content.length); - responseHeaders.setContentType(MediaType.APPLICATION_JSON); - responseHeaders.set("Content-Disposition", "attachment;filename=" + file.getName()); - responseHeaders.set("Access-Control-Expose-Headers", "Content-Disposition"); - responseHeaders.get("Access-Control-Expose-Headers").add("Content-Type"); - - - return new ResponseEntity<>(content, responseHeaders, HttpStatus.OK); - } -} diff --git a/dmp-backend/web/src/main/java/eu/eudat/controllers/v2/LanguageV2Controller.java b/dmp-backend/web/src/main/java/eu/eudat/controllers/v2/LanguageController.java similarity index 94% rename from dmp-backend/web/src/main/java/eu/eudat/controllers/v2/LanguageV2Controller.java rename to dmp-backend/web/src/main/java/eu/eudat/controllers/v2/LanguageController.java index 065bbe603..7b694fb1c 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/controllers/v2/LanguageV2Controller.java +++ b/dmp-backend/web/src/main/java/eu/eudat/controllers/v2/LanguageController.java @@ -13,7 +13,6 @@ import eu.eudat.model.result.QueryResult; import eu.eudat.query.LanguageQuery; import eu.eudat.query.lookup.LanguageLookup; import eu.eudat.service.language.LanguageService; -import gr.cite.commons.web.authz.service.AuthorizationService; import gr.cite.tools.auditing.AuditService; import gr.cite.tools.data.builder.BuilderFactory; import gr.cite.tools.data.censor.CensorFactory; @@ -41,10 +40,10 @@ import java.util.UUID; import java.util.stream.Collectors; @RestController -@RequestMapping(path = {"api/v2/language"}) -public class LanguageV2Controller { +@RequestMapping(path = {"api/language"}) +public class LanguageController { - private static final LoggerService logger = new LoggerService(LoggerFactory.getLogger(LanguageV2Controller.class)); + private static final LoggerService logger = new LoggerService(LoggerFactory.getLogger(LanguageController.class)); private final BuilderFactory builderFactory; @@ -56,24 +55,21 @@ public class LanguageV2Controller { private final MessageSource messageSource; - private final AuthorizationService authorizationService; - private final LanguageService languageService; @Autowired - public LanguageV2Controller( + public LanguageController( BuilderFactory builderFactory, AuditService auditService, CensorFactory censorFactory, QueryFactory queryFactory, - MessageSource messageSource, AuthorizationService authorizationService, + MessageSource messageSource, LanguageService languageService) { this.builderFactory = builderFactory; this.auditService = auditService; this.censorFactory = censorFactory; this.queryFactory = queryFactory; this.messageSource = messageSource; - this.authorizationService = authorizationService; this.languageService = languageService; } @@ -112,7 +108,7 @@ public class LanguageV2Controller { return model; } - @GetMapping("code/{code}") + @GetMapping("public/code/{code}") public Language get(@PathVariable("code") String code, FieldSet fieldSet) throws MyApplicationException, MyForbiddenException, MyNotFoundException, IOException { logger.debug(new MapLogEntry("retrieving" + Language.class.getSimpleName()).And("code", code).And("fields", fieldSet)); @@ -135,7 +131,7 @@ public class LanguageV2Controller { return model; } - @PostMapping("available-languages") + @PostMapping("public/available-languages") public QueryResult queryLanguageCodes(@RequestBody LanguageLookup lookup) { logger.debug("querying {}", Language.class.getSimpleName()); diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/ContactEmailManager.java b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/ContactEmailManager.java deleted file mode 100644 index 239ed6d38..000000000 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/ContactEmailManager.java +++ /dev/null @@ -1,69 +0,0 @@ -package eu.eudat.logic.managers; - -import eu.eudat.commons.scope.user.UserScope; -import eu.eudat.data.UserEntity; -import eu.eudat.logic.services.ApiContext; -import eu.eudat.model.UserContactInfo; -import eu.eudat.models.data.ContactEmail.ContactEmailModel; -import eu.eudat.models.data.ContactEmail.PublicContactEmailModel; -import eu.eudat.query.UserContactInfoQuery; -import eu.eudat.query.UserQuery; -import gr.cite.tools.data.query.Ordering; -import gr.cite.tools.data.query.QueryFactory; -import org.springframework.core.env.Environment; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; - -import jakarta.mail.MessagingException; - -import javax.management.InvalidApplicationException; - -@Component -public class ContactEmailManager { - - private ApiContext apiContext; - private Environment environment; - private final UserScope userScope; - private final QueryFactory queryFactory; - @Autowired - public ContactEmailManager(ApiContext apiContext, Environment environment, UserScope userScope, QueryFactory queryFactory) { - this.apiContext = apiContext; - this.environment = environment; - this.userScope = userScope; - this.queryFactory = queryFactory; - } - - public void sendContactEmail(ContactEmailModel contactEmailModel) throws MessagingException, InvalidApplicationException { -// UserEntity user = this.queryFactory.query(UserQuery.class).ids(this.userScope.getUserId()).first(); -// SimpleMail mail = new SimpleMail(); -// UserContactInfoQuery query = this.queryFactory.query(UserContactInfoQuery.class).userIds(user.getId()); -// query.setOrder(new Ordering().addAscending(UserContactInfo._ordinal)); -// String enrichedMail = contactEmailModel.getDescription() + "\n\n" + "Send by user: " + query.first().getValue() ; -// mail.setSubject(contactEmailModel.getSubject()); -// mail.setTo(environment.getProperty("contact_email.mail")); -// mail.setContent(enrichedMail); -// mail.setFrom(query.first().getValue()); -// -// apiContext.getUtilitiesService().getMailService().sendSimpleMail(mail); - } - - public void sendContactEmailNoAuth(PublicContactEmailModel contactEmailModel) throws MessagingException { -// SimpleMail mail = new SimpleMail(); -// String enrichedMail = contactEmailModel.getMessage() + "\n\n" + "Send by user: " + contactEmailModel.getEmail() ; -// mail.setSubject(contactEmailModel.getAffiliation()); -// mail.setTo(environment.getProperty("contact_email.mail")); -// mail.setContent(enrichedMail); -// mail.setFrom(contactEmailModel.getEmail()); -// -// apiContext.getUtilitiesService().getMailService().sendSimpleMail(mail); - } - - public void emailValidation(ContactEmailModel contactEmailModel) throws Exception { - if (contactEmailModel.getSubject() == null || contactEmailModel.getSubject().trim().isEmpty()) { - throw new Exception("Subject is empty"); - } - if (contactEmailModel.getDescription() == null || contactEmailModel.getDescription().trim().isEmpty()) { - throw new Exception("Description is empty"); - } - } -} diff --git a/dmp-backend/web/src/main/resources/config/security.yml b/dmp-backend/web/src/main/resources/config/security.yml index 8c506e9c7..e9bcfc699 100644 --- a/dmp-backend/web/src/main/resources/config/security.yml +++ b/dmp-backend/web/src/main/resources/config/security.yml @@ -2,7 +2,7 @@ web: security: enabled: true authorized-endpoints: [ api ] - allowed-endpoints: [ api/public, api/description/public, api/contact-support/public, api/dashboard/public ] + allowed-endpoints: [ api/public, api/description/public, api/language/public, api/contact-support/public, api/dashboard/public ] idp: api-key: enabled: false diff --git a/dmp-frontend/src/app/core/services/dashboard/dashboard.service.ts b/dmp-frontend/src/app/core/services/dashboard/dashboard.service.ts index 5c82b3a14..5a2b4b295 100644 --- a/dmp-frontend/src/app/core/services/dashboard/dashboard.service.ts +++ b/dmp-frontend/src/app/core/services/dashboard/dashboard.service.ts @@ -7,6 +7,8 @@ import { Observable, throwError } from 'rxjs'; import { catchError } from 'rxjs/operators'; import { ConfigurationService } from '../configuration/configuration.service'; import { BaseHttpV2Service } from '../http/base-http-v2.service'; +import { BaseHttpParams } from '@common/http/base-http-params'; +import { InterceptorType } from '@common/http/interceptors/interceptor-type'; @Injectable() export class DashboardService { @@ -33,6 +35,10 @@ export class DashboardService { getPublicDashboardStatistics(): Observable { const url = `${this.apiBase}/public/get-statistics`; - return this.http.get(url).pipe(catchError((error: any) => throwError(error))); + const params = new BaseHttpParams(); + params.interceptorContext = { + excludedInterceptors: [InterceptorType.AuthToken] + }; + return this.http.get(url, { params: params }).pipe(catchError((error: any) => throwError(error))); } } diff --git a/dmp-frontend/src/app/core/services/description/description.service.ts b/dmp-frontend/src/app/core/services/description/description.service.ts index 69725a8c9..e27e95092 100644 --- a/dmp-frontend/src/app/core/services/description/description.service.ts +++ b/dmp-frontend/src/app/core/services/description/description.service.ts @@ -1,4 +1,4 @@ -import { HttpClient, HttpHeaders, HttpResponse } from '@angular/common/http'; +import { HttpClient, HttpHeaders, HttpParamsOptions, HttpResponse } from '@angular/common/http'; import { Injectable } from '@angular/core'; import { IsActive } from '@app/core/common/enum/is-active.enum'; import { Description, DescriptionPersist, DescriptionStatusPersist, PublicDescription } from '@app/core/model/description/description'; @@ -14,6 +14,8 @@ import { nameof } from 'ts-simple-nameof'; import { ConfigurationService } from '../configuration/configuration.service'; import { BaseHttpV2Service } from '../http/base-http-v2.service'; import { FileFormat } from '@app/core/model/file/file-format.model'; +import { BaseHttpParams } from '@common/http/base-http-params'; +import { InterceptorType } from '@common/http/interceptors/interceptor-type'; @Injectable() export class DescriptionService { @@ -32,15 +34,24 @@ export class DescriptionService { publicQuery(q: DescriptionLookup): Observable> { const url = `${this.apiBase}/public/query`; - return this.http.post>(url, q).pipe(catchError((error: any) => throwError(error))); + const params = new BaseHttpParams(); + params.interceptorContext = { + excludedInterceptors: [InterceptorType.AuthToken] + }; + return this.http.post>(url, q, { params: params }).pipe(catchError((error: any) => throwError(error))); } getSingle(id: Guid, reqFields: string[] = []): Observable { const url = `${this.apiBase}/${id}`; - const options = { params: { f: reqFields } }; + const options: HttpParamsOptions = { fromObject: { f: reqFields } }; + + let params: BaseHttpParams = new BaseHttpParams(options); + params.interceptorContext = { + excludedInterceptors: [InterceptorType.AuthToken] + }; return this.http - .get(url, options).pipe( + .get(url, { params: params }).pipe( catchError((error: any) => throwError(error))); } diff --git a/dmp-frontend/src/app/core/services/dmp/dmp.service.ts b/dmp-frontend/src/app/core/services/dmp/dmp.service.ts index 722cd8ac9..378dc97f0 100644 --- a/dmp-frontend/src/app/core/services/dmp/dmp.service.ts +++ b/dmp-frontend/src/app/core/services/dmp/dmp.service.ts @@ -1,4 +1,4 @@ -import { HttpClient, HttpHeaders, HttpResponse } from '@angular/common/http'; +import { HttpClient, HttpHeaders, HttpParamsOptions, HttpResponse } from '@angular/common/http'; import { Injectable } from '@angular/core'; import { DmpStatus } from '@app/core/common/enum/dmp-status'; import { DmpUserRole } from '@app/core/common/enum/dmp-user-role'; @@ -52,10 +52,15 @@ export class DmpService { getPublicSingle(id: Guid, reqFields: string[] = []): Observable { //TODO: add this to backend. const url = `${this.apiBase}/public/${id}`; - const options = { params: { f: reqFields } }; + const options: HttpParamsOptions = { fromObject: { f: reqFields } }; + + let params: BaseHttpParams = new BaseHttpParams(options); + params.interceptorContext = { + excludedInterceptors: [InterceptorType.AuthToken] + }; return this.http - .get(url, options).pipe( + .get(url, { params: params }).pipe( catchError((error: any) => throwError(error))); } @@ -219,4 +224,4 @@ export class DmpService { isDmpOwner(dmpUsers: DmpUser[]): Boolean { return this.getCurrentUserRolesInDmp(dmpUsers).includes(DmpUserRole.Owner); } -} \ No newline at end of file +} diff --git a/dmp-frontend/src/app/core/services/language/language.http.service.ts b/dmp-frontend/src/app/core/services/language/language.http.service.ts index aff0f3a79..729b87297 100644 --- a/dmp-frontend/src/app/core/services/language/language.http.service.ts +++ b/dmp-frontend/src/app/core/services/language/language.http.service.ts @@ -12,6 +12,9 @@ import { catchError, map } from 'rxjs/operators'; import { nameof } from 'ts-simple-nameof'; import { ConfigurationService } from '../configuration/configuration.service'; import { BaseHttpV2Service } from '../http/base-http-v2.service'; +import { InterceptorType } from '@common/http/interceptors/interceptor-type'; +import { BaseHttpParams } from '@common/http/base-http-params'; +import { HttpParamsOptions } from '@angular/common/http'; @Injectable() export class LanguageHttpService { @@ -19,7 +22,7 @@ export class LanguageHttpService { constructor(private http: BaseHttpV2Service, private configurationService: ConfigurationService, private filterService: FilterService) { } - private get apiBase(): string { return `${this.configurationService.server}v2/language`; } + private get apiBase(): string { return `${this.configurationService.server}language`; } query(q: LanguageLookup): Observable> { const url = `${this.apiBase}/query`; @@ -36,17 +39,26 @@ export class LanguageHttpService { } getSingleWithCode(code: string, reqFields: string[] = []): Observable { - const url = `${this.apiBase}/code/${code}`; - const options = { params: { f: reqFields } }; + const url = `${this.apiBase}/public/code/${code}`; + const options: HttpParamsOptions = { fromObject: { f: reqFields } }; + + let params: BaseHttpParams = new BaseHttpParams(options); + params.interceptorContext = { + excludedInterceptors: [InterceptorType.AuthToken] + }; return this.http - .get(url, options).pipe( + .get(url, { params: params }).pipe( catchError((error: any) => throwError(error))); } queryAvailableCodes(q: LanguageLookup): Observable> { - const url = `${this.apiBase}/available-languages`; - return this.http.post>(url, q).pipe(catchError((error: any) => throwError(error))); + const url = `${this.apiBase}/public/available-languages`; + const params = new BaseHttpParams(); + params.interceptorContext = { + excludedInterceptors: [InterceptorType.AuthToken] + }; + return this.http.post>(url, q, { params: params }).pipe(catchError((error: any) => throwError(error))); } persist(item: LanguagePersist): Observable { @@ -104,4 +116,4 @@ export class LanguageHttpService { if (like) { lookup.like = this.filterService.transformLike(like); } return lookup; } -} \ No newline at end of file +} diff --git a/dmp-frontend/src/app/core/services/language/server.loader.ts b/dmp-frontend/src/app/core/services/language/server.loader.ts index 007e8e892..380547469 100644 --- a/dmp-frontend/src/app/core/services/language/server.loader.ts +++ b/dmp-frontend/src/app/core/services/language/server.loader.ts @@ -14,7 +14,7 @@ export class TranslateServerLoader implements TranslateLoader { } getTranslation(lang: string): Observable { return this.languageHttpService.getSingleWithCode(lang, [ - ...nameof(x => x.id), + nameof(x => x.id), nameof(x => x.code), nameof(x => x.payload), ]).pipe(map(x => JSON.parse(x.payload)));