diff --git a/server/build.gradle b/server/build.gradle index d62c80c..5e22158 100644 --- a/server/build.gradle +++ b/server/build.gradle @@ -1,15 +1,15 @@ buildscript { ext { - appVersion = "0.0.1" + appVersion = "0.0.2" // versions (ordered alphabetically) checkStyleVersion = "8.28" - flywayVersion = "5.0.7" + flywayVersion = "6.3.3" javaassistVersion = "3.26.0-GA" jaxbVersion = 2.1 - jwtVersion = "0.9.0" - lombokVersion = "1.18.10" - refVersion = "0.9.11" - springBootVersion = "2.0.2.RELEASE" // keep synced with plugin org.springframework.boot declared below + jwtVersion = "0.9.1" + lombokVersion = "1.18.12" + refVersion = "0.9.12" + springBootVersion = "2.2.6.RELEASE" // keep synced with plugin org.springframework.boot declared below targetSource = 1.8 // other vars apiDocsFolder = "apidocs" @@ -20,12 +20,12 @@ buildscript { } plugins { - id "com.github.kt3k.coveralls" version "2.8.4" // coverage reports for coveralls.io + id "com.github.kt3k.coveralls" version "2.10.1" // coverage reports for coveralls.io id "com.moowork.node" version "1.3.1" - id "io.spring.dependency-management" version "1.0.8.RELEASE" - id "net.saliman.cobertura" version "2.6.1" // coverage generator - id "org.asciidoctor.convert" version "2.3.0" - id "org.springframework.boot" version "2.0.2.RELEASE" // keep synced with var springBootVersion + id "io.spring.dependency-management" version "1.0.9.RELEASE" + id "net.saliman.cobertura" version "3.0.0" // coverage generator + id "org.asciidoctor.convert" version "2.4.0" + id "org.springframework.boot" version "2.2.6.RELEASE" // keep synced with var springBootVersion id 'checkstyle' } @@ -50,36 +50,40 @@ node { dependencies { annotationProcessor ("org.projectlombok:lombok:${lombokVersion}") - - compile ("io.jsonwebtoken:jjwt:${jwtVersion}") - compile ("org.flywaydb:flyway-core:${flywayVersion}") - compile ("org.reflections:reflections:${refVersion}") - compile ("org.springframework.boot:spring-boot-configuration-processor:${springBootVersion}") - compile ("org.springframework.boot:spring-boot-starter-data-jpa") - compile ("org.springframework.boot:spring-boot-starter-data-rest") - compile ("org.springframework.boot:spring-boot-starter-hateoas") - compile ("org.springframework.boot:spring-boot-starter-mail") - compile ("org.springframework.boot:spring-boot-starter-security") - compile ("org.springframework.boot:spring-boot-starter-web") - compile ("javax.xml.bind:jaxb-api:${jaxbVersion}") - compile ("org.javassist:javassist:${javaassistVersion}") - + annotationProcessor ("org.springframework.boot:spring-boot-configuration-processor") + + implementation ("io.jsonwebtoken:jjwt:${jwtVersion}") + implementation ("org.flywaydb:flyway-core:${flywayVersion}") + implementation ("org.reflections:reflections:${refVersion}") + implementation ("org.springframework.boot:spring-boot-starter-data-jpa") + implementation ("org.springframework.boot:spring-boot-starter-data-rest") + implementation ("org.springframework.boot:spring-boot-starter-hateoas") + implementation ("org.springframework.boot:spring-boot-starter-mail") + implementation ("org.springframework.boot:spring-boot-starter-security") + implementation ("org.springframework.boot:spring-boot-starter-web") + implementation ("javax.xml.bind:jaxb-api:${jaxbVersion}") + implementation ("org.javassist:javassist:${javaassistVersion}") compileOnly ("org.projectlombok:lombok:${lombokVersion}") - runtime ("org.postgresql:postgresql") - runtime ("org.springframework.boot:spring-boot-devtools") + runtimeOnly ("org.postgresql:postgresql") + runtimeOnly ("org.springframework.boot:spring-boot-devtools") + + testImplementation ("com.jayway.jsonpath:json-path") + testImplementation ("org.springframework.boot:spring-boot-starter-test") + testImplementation ("org.springframework.restdocs:spring-restdocs-mockmvc") + testImplementation ("org.springframework.security:spring-security-test") - testCompile ("com.jayway.jsonpath:json-path") - testCompile ("org.springframework.boot:spring-boot-starter-test") - testCompile ("org.springframework.restdocs:spring-restdocs-mockmvc") - testCompile ("org.springframework.security:spring-security-test") + testCompileOnly ("org.projectlombok:lombok:${lombokVersion}") + testAnnotationProcessor ("org.projectlombok:lombok:${lombokVersion}") } //region custom tasks //region client task -task clientBuild(type: NpmTask, dependsOn: ["npmInstall", "copyClientDocBuild", "configPackageJsonDeployUrl", "configPackageJsonBaseUrl"]) { +task clientBuild(type: NpmTask, dependsOn: ["npmInstall", "copyClientDocBuild", "configPackageJsonDeployUrl", + "configPackageJsonBaseUrl"] + ) { group = "client" description = "Compiles client side folder for production" args = ["run", "build"] @@ -112,7 +116,8 @@ task clientDocBuild(type: NpmTask, dependsOn: ["npmInstall"]) { task copyClientDocBuild(type: Copy, dependsOn: ["clientDocBuild"]) { group = "client" - description = "Checks all client app documentation resources are ready for deployment and copy them into the `static` folder" + description = """Checks all client app documentation resources are ready for deployment and copy them into the + `static` folder""" from "../client/documentation" into "build/resources/main/static/appdocs" } @@ -130,12 +135,14 @@ task setDevConfig() { group = "other" description = "Sets the environment for development mode" doFirst { - def p = getSpringAppPropertyInBuild("spring.profiles.active") - if (p && p != "development") { + final def property = getSpringAppPropertyInBuild("spring.profiles.active") + if (property && property != "development") { ant.propertyfile(file: buildPropertiesFilePath) { entry(key: "spring.profiles.active", value: "development") } envSet = true + + return } } doLast { @@ -149,12 +156,14 @@ task setTestingConfig() { group = "other" description = "Sets the environment for testing mode" doFirst { - def p = getSpringAppPropertyInBuild("spring.profiles.active") - if (p && p != "test") { + final def property = getSpringAppPropertyInBuild("spring.profiles.active") + if (property && property != "test") { ant.propertyfile(file: buildPropertiesFilePath) { entry(key: "spring.profiles.active", value: "test") } envSet = true + + return } } doLast { @@ -168,12 +177,14 @@ task setProductionConfig() { group = "other" description = "Sets the environment for production mode" doFirst { - def p = getSpringAppPropertyInBuild("spring.profiles.active") - if (p && p != "production") { + final def property = getSpringAppPropertyInBuild("spring.profiles.active") + if (property && property != "production") { ant.propertyfile(file: buildPropertiesFilePath) { entry(key: "spring.profiles.active", value: "production") } envSet = true + + return } } doLast { @@ -184,18 +195,18 @@ task setProductionConfig() { } @SuppressWarnings("GrMethodMayBeStatic") -private String getSpringAppPropertyInBuild(String key, String filePath = null){ - def props = new Properties() - def propFile = new File(filePath ?: buildPropertiesFilePath) - def p = null +private String getSpringAppPropertyInBuild(final String propertyKey, final String filePath = null) { + final def props = new Properties() + final def propFile = new File(filePath ?: buildPropertiesFilePath) + def property = null if (propFile.exists() && propFile.canRead()){ props.load(new FileInputStream(propFile)) - if (props!=null && props.containsKey(key)) { - p = props[key] + if (props != null && props.containsKey(propertyKey)) { + property = props[propertyKey] } } - return p + return property } //endregion @@ -272,7 +283,7 @@ testClasses.dependsOn(setTestingConfig) bootWar { dependsOn setProductionConfig, processApiDocs, copyClientBuild - baseName = getAppName() + archivesBaseName = getAppName() } // In order to generate our own metadata by Using the Annotation Processor @@ -295,13 +306,15 @@ private String getAppName() { } private String getClientDeployUrl() { - String defaultUrl = "/${getAppName()}-${version}/" - String configUrl = project.getProperties().get("clientDeployUrl") + final String defaultUrl = "/${getAppName()}-${version}/" + final String configUrl = project.getProperties().get("clientDeployUrl") + return (configUrl || configUrl == "") ? (configUrl == "" ? "" : configUrl) : defaultUrl } private String getClientBaseUrl() { - String defaultUrl = "/${getAppName()}-${version}/" - String configUrl = project.getProperties().get("clientBaseUrl") - return configUrl ? configUrl : defaultUrl -} \ No newline at end of file + final String defaultUrl = "/${getAppName()}-${version}/" + final String configUrl = project.getProperties().get("clientBaseUrl") + + return configUrl ?: defaultUrl +} diff --git a/server/src/main/asciidoc/index.adoc b/server/src/main/asciidoc/index.adoc index c8bff5a..9b97e4e 100644 --- a/server/src/main/asciidoc/index.adoc +++ b/server/src/main/asciidoc/index.adoc @@ -13,4 +13,6 @@ include::overview/index.adoc[] include::security/index.adoc[] -include::resources/index.adoc[] \ No newline at end of file +include::language/index.adoc[] + +include::resources/index.adoc[] diff --git a/server/src/main/asciidoc/language/example/language-header-en.adoc b/server/src/main/asciidoc/language/example/language-header-en.adoc new file mode 100644 index 0000000..0528272 --- /dev/null +++ b/server/src/main/asciidoc/language/example/language-header-en.adoc @@ -0,0 +1,11 @@ +include::../../util/H-REQUEST.adoc[] + +include::../../util/H-EXAMPLE.adoc[] + +include::{snippets}/locale-config-test/delete-roles-e-n/curl-request.adoc[] + +include::../../util/H-RESPONSE.adoc[] + +include::../../util/H-EXAMPLE-BARE.adoc[] + +include::{snippets}/locale-config-test/delete-roles-e-n/http-response.adoc[] diff --git a/server/src/main/asciidoc/language/example/language-param-es.adoc b/server/src/main/asciidoc/language/example/language-param-es.adoc new file mode 100644 index 0000000..ed77b07 --- /dev/null +++ b/server/src/main/asciidoc/language/example/language-param-es.adoc @@ -0,0 +1,11 @@ +include::../../util/H-REQUEST.adoc[] + +include::../../util/H-EXAMPLE.adoc[] + +include::{snippets}/locale-config-test/delete-roles-e-s/curl-request.adoc[] + +include::../../util/H-RESPONSE.adoc[] + +include::../../util/H-EXAMPLE-BARE.adoc[] + +include::{snippets}/locale-config-test/delete-roles-e-s/http-response.adoc[] diff --git a/server/src/main/asciidoc/language/index.adoc b/server/src/main/asciidoc/language/index.adoc new file mode 100644 index 0000000..a1f305c --- /dev/null +++ b/server/src/main/asciidoc/language/index.adoc @@ -0,0 +1,21 @@ +[[language]] +== Language + +By default all requests will be handled in English Language. Additionally there is support for the following languages: + + - Spanish + +The language in which the request will be handle can be specified in the following ways: + +[[sending-accept-language]] +=== Sending an `Accept-Language` header + +include::example/language-header-en.adoc[] + +[[sending-request-parameter]] +=== Sending a special parameter in the request (by default `lang`, but it may change due to server configuration) + +include::example/language-param-es.adoc[] + +[[sending-cookie]] +=== Sending a cookie diff --git a/server/src/main/asciidoc/resources/configuration/get-is-multi-entity.adoc b/server/src/main/asciidoc/resources/configuration/get-is-multi-entity.adoc index a139df2..10f5ae8 100644 --- a/server/src/main/asciidoc/resources/configuration/get-is-multi-entity.adoc +++ b/server/src/main/asciidoc/resources/configuration/get-is-multi-entity.adoc @@ -1,7 +1,7 @@ [[system-configuration-get-is-multientity]] ==== Getting whether the system is multi-entity or not -A `GET` request return `true` or `false` indicating whether the system is configured for managing multiple entities (`true`) or not (`false`). +A `GET` request returns `true` or `false` indicating whether the system is configured for managing multiple entities (`true`) or not (`false`). include::../../util/H-REQUEST.adoc[] diff --git a/server/src/main/asciidoc/resources/configuration/get-user-registration-allowed.adoc b/server/src/main/asciidoc/resources/configuration/get-user-registration-allowed.adoc index e204924..7165ba6 100644 --- a/server/src/main/asciidoc/resources/configuration/get-user-registration-allowed.adoc +++ b/server/src/main/asciidoc/resources/configuration/get-user-registration-allowed.adoc @@ -1,7 +1,7 @@ [[system-configuration-get-user-registration-allowed]] ==== Getting whether the system is configured for signing up new users or not -A `GET` request return `true` or `false` indicating whether new users can sign up (`true`) or not (`false`). +A `GET` request returns `true` or `false` indicating whether new users can sign up (`true`) or not (`false`). include::../../util/H-REQUEST.adoc[] diff --git a/server/src/main/asciidoc/resources/role/add-permissions.adoc b/server/src/main/asciidoc/resources/role/add-permissions.adoc index 48c3269..51fa4e3 100644 --- a/server/src/main/asciidoc/resources/role/add-permissions.adoc +++ b/server/src/main/asciidoc/resources/role/add-permissions.adoc @@ -1,7 +1,7 @@ [[resource-roles-add-permission]] ==== Adding permissions -A `POST` request add new permissions to a role if this has not this permission already assigned. +A `POST` request adds new permissions to a role if this has not this permission already assigned. This request does not delete eny of the existing permissions assigned to the role. include::../../util/H-REQUEST.adoc[] diff --git a/server/src/main/asciidoc/resources/role/update-permissions.adoc b/server/src/main/asciidoc/resources/role/update-permissions.adoc index 27e2e8e..a845536 100644 --- a/server/src/main/asciidoc/resources/role/update-permissions.adoc +++ b/server/src/main/asciidoc/resources/role/update-permissions.adoc @@ -1,7 +1,7 @@ [[resource-roles-update-permission]] ==== Updating permissions -A `PUT` request set the permissions for a role. +A `PUT` request sets the permissions for a role. This service sets the permissions with the `id` as the ones provided in the payload as the ones assigned to the specified role (through the `id` in the URL). This removes all previous permissions assigned to the role and adds the new ones. diff --git a/server/src/main/java/com/gms/Application.java b/server/src/main/java/com/gms/Application.java index 5895473..c0c9103 100644 --- a/server/src/main/java/com/gms/Application.java +++ b/server/src/main/java/com/gms/Application.java @@ -14,6 +14,7 @@ import org.springframework.context.annotation.Bean; import org.springframework.http.HttpStatus; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.security.crypto.password.PasswordEncoder; /** * Entry point to the application. @@ -77,12 +78,12 @@ public CommandLineRunner commandLineRunner(final AppService appService) { //bCrypt /** - * Creates a {@link BCryptPasswordEncoder} to be provided to the Spring framework. + * Creates a {@link PasswordEncoder} to be provided to the Spring framework. * - * @return A {@link BCryptPasswordEncoder}. + * @return A {@link PasswordEncoder}. */ @Bean - public BCryptPasswordEncoder bCryptPasswordEncoder() { + public PasswordEncoder gmsPasswordEncoder() { return new BCryptPasswordEncoder(); } diff --git a/server/src/main/java/com/gms/component/security/authentication/package-info.java b/server/src/main/java/com/gms/component/security/authentication/package-info.java deleted file mode 100644 index 2909289..0000000 --- a/server/src/main/java/com/gms/component/security/authentication/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -/** - * This package contains classes to handle the session state. - */ -package com.gms.component.security.authentication; diff --git a/server/src/main/java/com/gms/config/DefaultControllerAdvice.java b/server/src/main/java/com/gms/config/DefaultControllerAdvice.java index ebb1683..e3f8847 100644 --- a/server/src/main/java/com/gms/config/DefaultControllerAdvice.java +++ b/server/src/main/java/com/gms/config/DefaultControllerAdvice.java @@ -1,6 +1,6 @@ package com.gms.config; -import com.gms.component.security.authentication.AuthenticationFacade; +import com.gms.config.security.authentication.AuthenticationFacade; import com.gms.util.constant.DefaultConst; import com.gms.util.exception.ExceptionUtil; import com.gms.util.exception.GmsGeneralException; diff --git a/server/src/main/java/com/gms/config/RepositoryConfig.java b/server/src/main/java/com/gms/config/RepositoryConfig.java index 2087779..b592ee9 100644 --- a/server/src/main/java/com/gms/config/RepositoryConfig.java +++ b/server/src/main/java/com/gms/config/RepositoryConfig.java @@ -4,7 +4,7 @@ import org.reflections.scanners.SubTypesScanner; import org.springframework.context.annotation.Configuration; import org.springframework.data.rest.core.config.RepositoryRestConfiguration; -import org.springframework.data.rest.webmvc.config.RepositoryRestConfigurerAdapter; +import org.springframework.data.rest.webmvc.config.RepositoryRestConfigurer; import java.util.Set; @@ -15,7 +15,7 @@ * @version 0.1 */ @Configuration -public class RepositoryConfig extends RepositoryRestConfigurerAdapter { +public class RepositoryConfig implements RepositoryRestConfigurer { /** * This method is intended to be used by the Spring framework and should not be overridden. Doing so may produce diff --git a/server/src/main/java/com/gms/config/locale/GmsCLocaleResolver.java b/server/src/main/java/com/gms/config/locale/GmsCLocaleResolver.java index dd94147..34c5b37 100644 --- a/server/src/main/java/com/gms/config/locale/GmsCLocaleResolver.java +++ b/server/src/main/java/com/gms/config/locale/GmsCLocaleResolver.java @@ -23,7 +23,7 @@ public class GmsCLocaleResolver extends CookieLocaleResolver { public Locale resolveLocale(final HttpServletRequest request) { String acceptLanguage = request.getHeader(DefaultConst.DEFAULT_LANGUAGE_HEADER); if (acceptLanguage == null || acceptLanguage.trim().isEmpty()) { - return super.determineDefaultLocale(request); + return super.resolveLocale(request); } return request.getLocale(); diff --git a/server/src/main/java/com/gms/config/locale/LocaleConfig.java b/server/src/main/java/com/gms/config/locale/LocaleConfig.java index 24dc7fd..532dda0 100644 --- a/server/src/main/java/com/gms/config/locale/LocaleConfig.java +++ b/server/src/main/java/com/gms/config/locale/LocaleConfig.java @@ -6,71 +6,32 @@ import org.springframework.context.MessageSource; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.context.support.ReloadableResourceBundleMessageSource; import org.springframework.web.servlet.LocaleResolver; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; +import org.springframework.web.servlet.i18n.CookieLocaleResolver; import org.springframework.web.servlet.i18n.LocaleChangeInterceptor; -import java.io.File; -import java.nio.charset.StandardCharsets; +import java.util.Locale; /** * @author Asiel Leal Celdeiro | lealceldeiro@gmail.com - * @version 0.1 + * @version 0.2 */ @RequiredArgsConstructor @Configuration public class LocaleConfig implements WebMvcConfigurer { - /** - * File separator. - */ - private static final String SEP = File.pathSeparator; - /** - * Classpath for the resources. - */ - private static final String CLASSPATH = "classpath:"; - /** - * i18n path for the resources. - */ - private static final String I18N = "i18n"; - /** - * Base path for each of the i18n resources. - */ - private static final String BASE_PATH = CLASSPATH + SEP + I18N + SEP; - /** - * Base paths for the i18n resources. - */ - private static final String[] I_18_N_BASE_NAMES = { - BASE_PATH + "user", - BASE_PATH + "role", - BASE_PATH + "configuration", - BASE_PATH + "label", - BASE_PATH + "messages", - BASE_PATH + "frameworkoverride", - BASE_PATH + "validations", - BASE_PATH + "field", - }; /** * Instance of {@link DefaultConst}. */ private final DefaultConst dc; /** - * This method is intended to be used by the Spring framework and should not be overridden. Doing so may produce - * unexpected results. - * - * @return A {@link MessageSource} for the {@link #I_18_N_BASE_NAMES} paths. + * Strategy interface for resolving messages, with support for the parameterization and internationalization of + * such messages. */ - @Bean - public MessageSource messageSource() { - ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource(); - messageSource.setBasenames(I_18_N_BASE_NAMES); - messageSource.setDefaultEncoding(StandardCharsets.UTF_8.name()); - - return messageSource; - } + private final MessageSource messageSource; /** * This method is intended to be used by the Spring framework and should not be overridden. Doing so may produce @@ -79,8 +40,8 @@ public MessageSource messageSource() { * @return A {@link MessageResolver} for some {@code messageSource}. */ @Bean - public MessageResolver messageResolver() { - return new MessageResolver(messageSource()); + public MessageResolver gmsMessageResolver() { + return new MessageResolver(messageSource); } /** @@ -91,7 +52,10 @@ public MessageResolver messageResolver() { */ @Bean public LocaleResolver localeResolver() { - return new GmsCLocaleResolver(); + CookieLocaleResolver localeResolver = new GmsCLocaleResolver(); + localeResolver.setDefaultLocale(Locale.forLanguageTag(dc.getDefaultLanguage())); + + return localeResolver; } /** diff --git a/server/src/main/java/com/gms/config/locale/package-info.java b/server/src/main/java/com/gms/config/locale/package-info.java index b57f2e5..2e50779 100644 --- a/server/src/main/java/com/gms/config/locale/package-info.java +++ b/server/src/main/java/com/gms/config/locale/package-info.java @@ -1,7 +1,7 @@ /** - * This package contains classes for handling i18n and l10n. + * This package contains configuration classes for handling i18n and l10n. * * @author Asiel Leal Celdeiro | lealceldeiro@gmail.com - * @version 0.1 + * @version 0.2 */ package com.gms.config.locale; diff --git a/server/src/main/java/com/gms/config/package-info.java b/server/src/main/java/com/gms/config/package-info.java index cf00698..c9bfd75 100644 --- a/server/src/main/java/com/gms/config/package-info.java +++ b/server/src/main/java/com/gms/config/package-info.java @@ -2,6 +2,6 @@ * This package contains classes regarding springboot configuration. * * @author Asiel Leal Celdeiro | lealceldeiro@gmail.com - * @version 0.1 + * @version 0.2 */ package com.gms.config; diff --git a/server/src/main/java/com/gms/config/security/SecurityConfig.java b/server/src/main/java/com/gms/config/security/SecurityConfig.java index 390889f..674e0c0 100644 --- a/server/src/main/java/com/gms/config/security/SecurityConfig.java +++ b/server/src/main/java/com/gms/config/security/SecurityConfig.java @@ -1,18 +1,22 @@ package com.gms.config.security; import com.fasterxml.jackson.databind.ObjectMapper; -import com.gms.component.security.authentication.AuthenticationFacade; -import com.gms.component.security.token.JWTService; +import com.gms.config.security.authentication.AuthenticationFacade; +import com.gms.config.security.authentication.JWTAuthenticationFailureHandler; +import com.gms.config.security.authentication.JWTAuthenticationFilter; +import com.gms.config.security.authentication.entrypoint.GmsHttpStatusAndBodyEntryPoint; +import com.gms.config.security.authorization.GmsAccessDeniedHandler; +import com.gms.config.security.authorization.JWTAuthorizationFilter; import com.gms.domain.security.user.EUser; import com.gms.service.security.user.UserService; import com.gms.util.constant.DefaultConst; import com.gms.util.constant.SecurityConst; import com.gms.util.i18n.MessageResolver; import com.gms.util.request.mapping.security.RefreshTokenPayload; +import com.gms.util.security.token.JWTService; import lombok.RequiredArgsConstructor; import org.springframework.context.annotation.Bean; import org.springframework.http.HttpMethod; -import org.springframework.http.HttpStatus; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; import org.springframework.security.config.annotation.web.builders.HttpSecurity; @@ -20,8 +24,7 @@ import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.config.http.SessionCreationPolicy; import org.springframework.security.core.userdetails.UserDetailsService; -import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; -import org.springframework.security.web.authentication.HttpStatusEntryPoint; +import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.web.cors.CorsConfiguration; import org.springframework.web.cors.CorsConfigurationSource; import org.springframework.web.cors.UrlBasedCorsConfigurationSource; @@ -32,6 +35,8 @@ import java.util.HashMap; import java.util.Map; +import static org.springframework.http.HttpStatus.UNAUTHORIZED; + /** * @author Asiel Leal Celdeiro | lealceldeiro@gmail.com * @version 0.1 @@ -61,9 +66,9 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter { */ private final UserDetailsService userDetailsService; /** - * Bean {@link BCryptPasswordEncoder}. + * Bean {@link PasswordEncoder}. */ - private final BCryptPasswordEncoder passwordEncoder; + private final PasswordEncoder passwordEncoder; /** * Instance of {@link ObjectMapper}. */ @@ -94,7 +99,11 @@ protected void configure(final HttpSecurity http) throws Exception { authFilter.setPostOnly(true); authFilter.setAuthenticationFailureHandler(new JWTAuthenticationFailureHandler(dc, sc, msg)); http - .cors().and().formLogin().disable().csrf().disable().authorizeRequests() + .cors().and() + .httpBasic().disable() + .formLogin().disable() + .csrf().disable() + .authorizeRequests() .antMatchers(HttpMethod.GET, getFreeGet()).permitAll() .antMatchers(HttpMethod.POST, getFreePost()).permitAll() .antMatchers(getFreeAny()).permitAll() @@ -112,7 +121,8 @@ protected void configure(final HttpSecurity http) throws Exception { .and() // 401 instead as "unauthorized" response HttpStatus .exceptionHandling() - .authenticationEntryPoint(new HttpStatusEntryPoint(HttpStatus.UNAUTHORIZED)); + .accessDeniedHandler(new GmsAccessDeniedHandler(dc, msg)) + .authenticationEntryPoint(new GmsHttpStatusAndBodyEntryPoint(UNAUTHORIZED, dc, msg)); } /** diff --git a/server/src/main/java/com/gms/component/security/authentication/AuthenticationFacade.java b/server/src/main/java/com/gms/config/security/authentication/AuthenticationFacade.java similarity index 92% rename from server/src/main/java/com/gms/component/security/authentication/AuthenticationFacade.java rename to server/src/main/java/com/gms/config/security/authentication/AuthenticationFacade.java index 7a41f73..58a4b79 100644 --- a/server/src/main/java/com/gms/component/security/authentication/AuthenticationFacade.java +++ b/server/src/main/java/com/gms/config/security/authentication/AuthenticationFacade.java @@ -1,4 +1,4 @@ -package com.gms.component.security.authentication; +package com.gms.config.security.authentication; import org.springframework.security.core.Authentication; diff --git a/server/src/main/java/com/gms/component/security/authentication/AuthenticationFacadeImpl.java b/server/src/main/java/com/gms/config/security/authentication/AuthenticationFacadeImpl.java similarity index 81% rename from server/src/main/java/com/gms/component/security/authentication/AuthenticationFacadeImpl.java rename to server/src/main/java/com/gms/config/security/authentication/AuthenticationFacadeImpl.java index 2de67e0..dc27950 100644 --- a/server/src/main/java/com/gms/component/security/authentication/AuthenticationFacadeImpl.java +++ b/server/src/main/java/com/gms/config/security/authentication/AuthenticationFacadeImpl.java @@ -1,4 +1,4 @@ -package com.gms.component.security.authentication; +package com.gms.config.security.authentication; import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContextHolder; @@ -9,7 +9,7 @@ * @version 0.1 */ @Component -public final class AuthenticationFacadeImpl implements AuthenticationFacade { +final class AuthenticationFacadeImpl implements AuthenticationFacade { @Override public Authentication getAuthentication() { diff --git a/server/src/main/java/com/gms/config/security/JWTAuthenticationFailureHandler.java b/server/src/main/java/com/gms/config/security/authentication/JWTAuthenticationFailureHandler.java similarity index 77% rename from server/src/main/java/com/gms/config/security/JWTAuthenticationFailureHandler.java rename to server/src/main/java/com/gms/config/security/authentication/JWTAuthenticationFailureHandler.java index 26611e4..f1bc842 100644 --- a/server/src/main/java/com/gms/config/security/JWTAuthenticationFailureHandler.java +++ b/server/src/main/java/com/gms/config/security/authentication/JWTAuthenticationFailureHandler.java @@ -1,12 +1,13 @@ -package com.gms.config.security; +package com.gms.config.security.authentication; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; import com.gms.util.constant.DefaultConst; import com.gms.util.constant.SecurityConst; import com.gms.util.exception.ExceptionUtil; import com.gms.util.exception.GmsSecurityException; import com.gms.util.i18n.MessageResolver; import lombok.RequiredArgsConstructor; -import org.springframework.boot.configurationprocessor.json.JSONObject; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.security.core.AuthenticationException; @@ -22,7 +23,7 @@ * @version 0.1 */ @RequiredArgsConstructor -public class JWTAuthenticationFailureHandler implements AuthenticationFailureHandler { +public final class JWTAuthenticationFailureHandler implements AuthenticationFailureHandler { /** * Instance of {@link DefaultConst}. @@ -55,11 +56,13 @@ public void onAuthenticationFailure(final HttpServletRequest request, final Http } } - private String getBody() { - GmsSecurityException ex = new GmsSecurityException(sc.getSignInUrl(), + private String getBody() throws JsonProcessingException { + final GmsSecurityException ex = new GmsSecurityException(sc.getSignInUrl(), msg.getMessage("security.bad.credentials")); - return new JSONObject(ExceptionUtil.getResponseBodyForGmsSecurityException(ex, msg, dc)).toString(); + final ObjectMapper objectMapper = new ObjectMapper(); + + return objectMapper.writeValueAsString(ExceptionUtil.getResponseBodyForGmsSecurityException(ex, msg, dc)); } } diff --git a/server/src/main/java/com/gms/config/security/JWTAuthenticationFilter.java b/server/src/main/java/com/gms/config/security/authentication/JWTAuthenticationFilter.java similarity index 95% rename from server/src/main/java/com/gms/config/security/JWTAuthenticationFilter.java rename to server/src/main/java/com/gms/config/security/authentication/JWTAuthenticationFilter.java index 91d66fb..98678a4 100644 --- a/server/src/main/java/com/gms/config/security/JWTAuthenticationFilter.java +++ b/server/src/main/java/com/gms/config/security/authentication/JWTAuthenticationFilter.java @@ -1,8 +1,7 @@ -package com.gms.config.security; +package com.gms.config.security.authentication; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; -import com.gms.component.security.token.JWTService; import com.gms.domain.security.user.EUser; import com.gms.service.security.user.UserService; import com.gms.util.constant.DefaultConst; @@ -10,6 +9,7 @@ import com.gms.util.exception.ExceptionUtil; import com.gms.util.exception.GmsSecurityException; import com.gms.util.i18n.MessageResolver; +import com.gms.util.security.token.JWTService; import lombok.RequiredArgsConstructor; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; @@ -33,7 +33,7 @@ * @version 0.1 */ @RequiredArgsConstructor -public class JWTAuthenticationFilter extends UsernamePasswordAuthenticationFilter { +public final class JWTAuthenticationFilter extends UsernamePasswordAuthenticationFilter { /** * Instance of {@link AuthenticationManager}. @@ -125,7 +125,7 @@ protected void successfulAuthentication(final HttpServletRequest req, final Http String accessToken = jwtService.createToken(sub, authorities); Map claims = jwtService.getClaimsExtended(accessToken); - Date iat = (Date) claims.get(JWTService.ISSUED_AT); + Date iat = (Date) claims.get(jwtService.issuedAtKey()); String refreshToken = jwtService.createRefreshToken(sub, authorities); diff --git a/server/src/main/java/com/gms/config/security/authentication/entrypoint/GmsEntryPoint.java b/server/src/main/java/com/gms/config/security/authentication/entrypoint/GmsEntryPoint.java new file mode 100644 index 0000000..2287053 --- /dev/null +++ b/server/src/main/java/com/gms/config/security/authentication/entrypoint/GmsEntryPoint.java @@ -0,0 +1,13 @@ +package com.gms.config.security.authentication.entrypoint; + +import org.springframework.security.web.AuthenticationEntryPoint; + +/** + * Extends {@link AuthenticationEntryPoint} in order to provide custom means to customize the response on authentication + * failure requests. + * + * @author Asiel Leal Celdeiro | lealceldeiro@gmail.com + * @version 0.1 + */ +interface GmsEntryPoint extends AuthenticationEntryPoint { +} diff --git a/server/src/main/java/com/gms/config/security/authentication/entrypoint/GmsHttpStatusAndBodyEntryPoint.java b/server/src/main/java/com/gms/config/security/authentication/entrypoint/GmsHttpStatusAndBodyEntryPoint.java new file mode 100644 index 0000000..5d1e254 --- /dev/null +++ b/server/src/main/java/com/gms/config/security/authentication/entrypoint/GmsHttpStatusAndBodyEntryPoint.java @@ -0,0 +1,54 @@ +package com.gms.config.security.authentication.entrypoint; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.gms.util.constant.DefaultConst; +import com.gms.util.exception.GmsSecurityException; +import com.gms.util.i18n.MessageResolver; +import lombok.RequiredArgsConstructor; +import org.springframework.http.HttpStatus; +import org.springframework.security.core.AuthenticationException; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.io.PrintWriter; + +import static com.gms.util.exception.ExceptionUtil.getResponseBodyForGmsSecurityException; + +/** + * Provides custom means to customize the response on authentication failure requests by allowing to be set an + * {@link org.springframework.http.HttpStatus}. + * + * @author Asiel Leal Celdeiro | lealceldeiro@gmail.com + * @version 0.1 + */ +@RequiredArgsConstructor +public final class GmsHttpStatusAndBodyEntryPoint implements GmsEntryPoint { + /** + * {@link HttpStatus} to be sent in the response. + */ + private final HttpStatus httpStatus; + + /** + * An instance of a {@link DefaultConst}. + */ + private final DefaultConst dc; + /** + * An instance of a {@link MessageResolver}. + */ + private final MessageResolver msg; + + @Override + public void commence(final HttpServletRequest request, final HttpServletResponse response, + final AuthenticationException authException) throws IOException { + response.setStatus(httpStatus.value()); + try (PrintWriter writer = response.getWriter()) { + writer.print(new ObjectMapper().writeValueAsString(responseBody(request.getRequestURL().toString()))); + } + } + + private Object responseBody(final String url) { + // update latter to return objects with a different information as different HttpStatus are handled + return getResponseBodyForGmsSecurityException(new GmsSecurityException(url), msg, dc); + } +} diff --git a/server/src/main/java/com/gms/config/security/authentication/entrypoint/package-info.java b/server/src/main/java/com/gms/config/security/authentication/entrypoint/package-info.java new file mode 100644 index 0000000..270c64d --- /dev/null +++ b/server/src/main/java/com/gms/config/security/authentication/entrypoint/package-info.java @@ -0,0 +1,7 @@ +/** + * This package contains classes for providing custom means to customize the entry points for unauthorized requests. + * + * @author Asiel Leal Celdeiro | lealceldeiro@gmail.com + * @version 0.1 + */ +package com.gms.config.security.authentication.entrypoint; diff --git a/server/src/main/java/com/gms/config/security/authentication/package-info.java b/server/src/main/java/com/gms/config/security/authentication/package-info.java new file mode 100644 index 0000000..221b7d4 --- /dev/null +++ b/server/src/main/java/com/gms/config/security/authentication/package-info.java @@ -0,0 +1,7 @@ +/** + * This package contains classes in charge of handling the authentication and authorization flow. + * + * @author Asiel Leal Celdeiro | lealceldeiro@gmail.com + * @version 0.2 + */ +package com.gms.config.security.authentication; diff --git a/server/src/main/java/com/gms/config/security/authorization/GmsAccessDeniedHandler.java b/server/src/main/java/com/gms/config/security/authorization/GmsAccessDeniedHandler.java new file mode 100644 index 0000000..c2a8fa2 --- /dev/null +++ b/server/src/main/java/com/gms/config/security/authorization/GmsAccessDeniedHandler.java @@ -0,0 +1,50 @@ +package com.gms.config.security.authorization; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.gms.util.constant.DefaultConst; +import com.gms.util.exception.GmsSecurityException; +import com.gms.util.i18n.MessageResolver; +import lombok.RequiredArgsConstructor; +import org.springframework.http.HttpStatus; +import org.springframework.security.access.AccessDeniedException; +import org.springframework.security.web.access.AccessDeniedHandler; +import org.springframework.stereotype.Component; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.io.PrintWriter; + +import static com.gms.util.exception.ExceptionUtil.getResponseBodyForGmsSecurityException; + +/** + * Handles access denied to a resource. + * + * @author Asiel Leal Celdeiro | lealceldeiro@gmail.com + * @version 0.1 + */ +@Component +@RequiredArgsConstructor +public final class GmsAccessDeniedHandler implements AccessDeniedHandler { + /** + * An instance of a {@link DefaultConst}. + */ + private final DefaultConst dc; + /** + * An instance of a {@link MessageResolver}. + */ + private final MessageResolver msg; + + @Override + public void handle(final HttpServletRequest request, final HttpServletResponse response, + final AccessDeniedException accessDeniedException) throws IOException { + final GmsSecurityException exception = new GmsSecurityException(request.getRequestURL().toString()); + final Object body = getResponseBodyForGmsSecurityException(exception, msg, dc); + + response.setStatus(HttpStatus.UNAUTHORIZED.value()); + try (PrintWriter writer = response.getWriter()) { + writer.print(new ObjectMapper().writeValueAsString(body)); + } + } + +} diff --git a/server/src/main/java/com/gms/config/security/JWTAuthorizationFilter.java b/server/src/main/java/com/gms/config/security/authorization/JWTAuthorizationFilter.java similarity index 85% rename from server/src/main/java/com/gms/config/security/JWTAuthorizationFilter.java rename to server/src/main/java/com/gms/config/security/authorization/JWTAuthorizationFilter.java index d0d55b0..21634d5 100644 --- a/server/src/main/java/com/gms/config/security/JWTAuthorizationFilter.java +++ b/server/src/main/java/com/gms/config/security/authorization/JWTAuthorizationFilter.java @@ -1,8 +1,8 @@ -package com.gms.config.security; +package com.gms.config.security.authorization; -import com.gms.component.security.authentication.AuthenticationFacade; -import com.gms.component.security.token.JWTService; +import com.gms.config.security.authentication.AuthenticationFacade; import com.gms.util.constant.SecurityConst; +import com.gms.util.security.token.JWTService; import io.jsonwebtoken.JwtException; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; @@ -21,7 +21,7 @@ * @author Asiel Leal Celdeiro | lealceldeiro@gmail.com * @version 0.1 */ -public class JWTAuthorizationFilter extends BasicAuthenticationFilter { +public final class JWTAuthorizationFilter extends BasicAuthenticationFilter { /** * Instance of {@link SecurityConst}. @@ -90,16 +90,16 @@ private UsernamePasswordAuthenticationToken getAuthToken(final HttpServletReques Map claims = jwtService.getClaimsExtended( token.replace(sc.getATokenType(), ""), sc.getAuthoritiesHolder(), PASS_HOLDER ); - String user = claims.get(JWTService.SUBJECT).toString(); + String user = claims.get(jwtService.subjectKey()).toString(); if (user != null) { // split into an array the string holding the authorities by the defined separator - final String[] authoritiesS = claims - .get(sc.getAuthoritiesHolder()).toString() - .split(SecurityConst.AUTHORITIES_SEPARATOR); - if (authoritiesS.length > 0) { + final String[] authorityValues = claims.get(sc.getAuthoritiesHolder()) + .toString() + .split(SecurityConst.AUTHORITIES_SEPARATOR); + if (authorityValues.length > 0) { HashSet authorities = new HashSet<>(); - for (String a : authoritiesS) { - authorities.add(new SimpleGrantedAuthority(a)); + for (String authorityValue : authorityValues) { + authorities.add(new SimpleGrantedAuthority(authorityValue)); } String password = String.valueOf(claims.get(PASS_HOLDER)); // hashed password diff --git a/server/src/main/java/com/gms/config/security/authorization/package-info.java b/server/src/main/java/com/gms/config/security/authorization/package-info.java new file mode 100644 index 0000000..7f77f8b --- /dev/null +++ b/server/src/main/java/com/gms/config/security/authorization/package-info.java @@ -0,0 +1,7 @@ +/** + * This package contains classes in charge of handling the authorization flow. + * + * @author Asiel Leal Celdeiro | lealceldeiro@gmail.com + * @version 0.1 + */ +package com.gms.config.security.authorization; diff --git a/server/src/main/java/com/gms/controller/configuration/ConfigurationController.java b/server/src/main/java/com/gms/controller/configuration/ConfigurationController.java index 40c5c45..5fdba52 100644 --- a/server/src/main/java/com/gms/controller/configuration/ConfigurationController.java +++ b/server/src/main/java/com/gms/controller/configuration/ConfigurationController.java @@ -6,6 +6,7 @@ import com.gms.util.exception.domain.NotFoundEntityException; import lombok.RequiredArgsConstructor; import org.springframework.http.HttpStatus; +import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestBody; @@ -63,6 +64,7 @@ public boolean isMultiEntity() { * @return Object which represent the configuration value for the given parameters. */ @GetMapping + @PreAuthorize("hasAuthority('MANAGE_CONFIGURATION')") public Object getConfig(@RequestParam(value = "key", required = false) final String key, @RequestParam(value = "id", required = false) final Long id) throws NotFoundEntityException { @@ -77,6 +79,7 @@ public Object getConfig(@RequestParam(value = "key", required = false) final Str * @return Map which represent the configurations key-value pairs for the given parameter. */ @GetMapping("{id}") + @PreAuthorize("isFullyAuthenticated()") public Map getConfigByUser(@PathVariable(value = "id") final Long id) { return configService.getConfigByUser(id); } @@ -92,6 +95,7 @@ public Map getConfigByUser(@PathVariable(value = "id") final Lon */ @RequestMapping(method = {RequestMethod.POST, RequestMethod.PUT}) @ResponseStatus(HttpStatus.NO_CONTENT) + @PreAuthorize("isFullyAuthenticated()") public void saveConfig(@RequestBody final Map configs) throws NotFoundEntityException, GmsGeneralException { configService.saveConfig(configs); diff --git a/server/src/main/java/com/gms/controller/security/SecurityController.java b/server/src/main/java/com/gms/controller/security/SecurityController.java index 50af0e3..5d6be5d 100644 --- a/server/src/main/java/com/gms/controller/security/SecurityController.java +++ b/server/src/main/java/com/gms/controller/security/SecurityController.java @@ -1,6 +1,6 @@ package com.gms.controller.security; -import com.gms.component.security.token.JWTService; +import com.gms.util.security.token.JWTService; import com.gms.domain.security.user.EUser; import com.gms.service.security.user.UserService; import com.gms.util.constant.SecurityConst; @@ -10,12 +10,11 @@ import io.jsonwebtoken.JwtException; import lombok.RequiredArgsConstructor; import org.springframework.data.rest.webmvc.BasePathAwareController; -import org.springframework.hateoas.Resource; +import org.springframework.hateoas.EntityModel; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.annotation.RestController; @@ -51,13 +50,12 @@ public class SecurityController { * results. * * @param user {@link EUser} data to be created - * @return A {@link EUser} mapped into a @{@link ResponseBody} + * @return A {@link EUser} mapped into a @{@link org.springframework.web.bind.annotation.ResponseBody} * @throws GmsGeneralException when an unhandled exception occurs. */ @PostMapping("${gms.security.sign_up_url}") @ResponseStatus(HttpStatus.CREATED) - @ResponseBody - public ResponseEntity signUpUser(@RequestBody @Valid final Resource user) + public ResponseEntity signUpUser(@RequestBody @Valid final EntityModel user) throws GmsGeneralException { EUser u = userService.signUp(user.getContent(), UserService.EmailStatus.NOT_VERIFIED); if (u != null) { @@ -85,9 +83,9 @@ public Map refreshToken(@Valid @RequestBody final RefreshTokenPa try { String[] keys = {sc.getAuthoritiesHolder()}; Map claims = jwtService.getClaimsExtended(oldRefreshToken, keys); - String sub = claims.get(JWTService.SUBJECT).toString(); + String sub = claims.get(jwtService.subjectKey()).toString(); String authorities = claims.get(keys[0]).toString(); - Date iat = (Date) claims.get(JWTService.ISSUED_AT); + Date iat = (Date) claims.get(jwtService.issuedAtKey()); String newAccessToken = jwtService.createToken(sub, authorities); String newRefreshToken = jwtService.createRefreshToken(sub, authorities); diff --git a/server/src/main/java/com/gms/controller/security/ownedentity/RestOwnedEntityController.java b/server/src/main/java/com/gms/controller/security/ownedentity/RestOwnedEntityController.java index a5e41f8..c726453 100644 --- a/server/src/main/java/com/gms/controller/security/ownedentity/RestOwnedEntityController.java +++ b/server/src/main/java/com/gms/controller/security/ownedentity/RestOwnedEntityController.java @@ -6,7 +6,7 @@ import com.gms.util.exception.GmsGeneralException; import lombok.RequiredArgsConstructor; import org.springframework.data.rest.webmvc.BasePathAwareController; -import org.springframework.hateoas.Resource; +import org.springframework.hateoas.EntityModel; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.PostMapping; @@ -43,7 +43,7 @@ public class RestOwnedEntityController { */ @PostMapping(path = ResourcePath.OWNED_ENTITY, produces = "application/hal+json") @ResponseStatus(HttpStatus.CREATED) - public ResponseEntity create(@Valid @RequestBody final Resource entity) + public ResponseEntity create(@Valid @RequestBody final EntityModel entity) throws GmsGeneralException { EOwnedEntity e = entityService.create(entity.getContent()); diff --git a/server/src/main/java/com/gms/controller/security/permission/PermissionController.java b/server/src/main/java/com/gms/controller/security/permission/PermissionController.java index 4ddd142..6690af4 100644 --- a/server/src/main/java/com/gms/controller/security/permission/PermissionController.java +++ b/server/src/main/java/com/gms/controller/security/permission/PermissionController.java @@ -8,16 +8,16 @@ import org.springframework.data.domain.Pageable; import org.springframework.data.rest.webmvc.BasePathAwareController; import org.springframework.data.web.PagedResourcesAssembler; +import org.springframework.hateoas.EntityModel; import org.springframework.hateoas.Link; -import org.springframework.hateoas.PagedResources; -import org.springframework.hateoas.Resource; +import org.springframework.hateoas.PagedModel; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.ResponseBody; -import static org.springframework.hateoas.mvc.ControllerLinkBuilder.linkTo; -import static org.springframework.hateoas.mvc.ControllerLinkBuilder.methodOn; +import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.linkTo; +import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.methodOn; /** * @author Asiel Leal Celdeiro | lealceldeiro@gmail.com @@ -39,12 +39,12 @@ public class PermissionController { * @param id {@link com.gms.domain.security.permission.BPermission} id to get the roles associated to. * @param pageable {@link Pageable} bean injected by spring. * @param pageAssembler {@link PagedResourcesAssembler} bean injected by spring. - * @return A {@link ResponseEntity} of PagedResources of {@link Resource} of {@link BRole} containing the requested + * @return A {@link ResponseEntity} of PagedModel of {@link EntityModel} of {@link BRole} containing the requested * information. */ @GetMapping(path = ResourcePath.PERMISSION + "/{id}/" + ResourcePath.ROLE + "s", produces = "application/hal+json") @ResponseBody - public ResponseEntity>> getAllRolesByPermission( + public ResponseEntity>> getAllRolesByPermission( @PathVariable final long id, final Pageable pageable, final PagedResourcesAssembler pageAssembler @@ -52,7 +52,7 @@ public ResponseEntity>> getAllRolesByPermission( Page page = permissionService.getAllRolesByPermissionId(id, pageable); Link link = linkTo(methodOn(PermissionController.class).getAllRolesByPermission(id, pageable, pageAssembler)) .withSelfRel(); - PagedResources> pagedResources = pageAssembler.toResource(page, link); + PagedModel> pagedResources = pageAssembler.toModel(page, link); return ResponseEntity.ok(pagedResources); } diff --git a/server/src/main/java/com/gms/controller/security/role/RoleController.java b/server/src/main/java/com/gms/controller/security/role/RoleController.java index 4287e59..dfa1819 100644 --- a/server/src/main/java/com/gms/controller/security/role/RoleController.java +++ b/server/src/main/java/com/gms/controller/security/role/RoleController.java @@ -9,9 +9,9 @@ import org.springframework.data.domain.Pageable; import org.springframework.data.rest.webmvc.BasePathAwareController; import org.springframework.data.web.PagedResourcesAssembler; +import org.springframework.hateoas.EntityModel; import org.springframework.hateoas.Link; -import org.springframework.hateoas.PagedResources; -import org.springframework.hateoas.Resource; +import org.springframework.hateoas.PagedModel; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; @@ -23,8 +23,8 @@ import java.util.List; -import static org.springframework.hateoas.mvc.ControllerLinkBuilder.linkTo; -import static org.springframework.hateoas.mvc.ControllerLinkBuilder.methodOn; +import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.linkTo; +import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.methodOn; /** * @author Asiel Leal Celdeiro | lealceldeiro@gmail.com @@ -101,12 +101,12 @@ public List updatePermissionsFromRole(@PathVariable final Long id, * @param id {@link com.gms.domain.security.role.BRole} id. * @param pageable {@link Pageable} bean injected by spring. * @param pageAssembler {@link PagedResourcesAssembler} bean injected by spring. - * @return A {@link ResponseEntity} of {@link PagedResources} of {@link Resource} of {@link BPermission} + * @return A {@link ResponseEntity} of {@link PagedModel} of {@link EntityModel} of {@link BPermission} * containing the requested information. */ @GetMapping(path = ResourcePath.ROLE + "/{id}/" + ResourcePath.PERMISSION + "s", produces = "application/hal+json") @ResponseBody - public ResponseEntity>> getAllPermissionsByRole( + public ResponseEntity>> getAllPermissionsByRole( @PathVariable final long id, final Pageable pageable, final PagedResourcesAssembler pageAssembler @@ -114,7 +114,7 @@ public ResponseEntity>> getAllPermissionsBy Page page = roleService.getAllPermissionsByRoleId(id, pageable); Link link = linkTo(methodOn(RoleController.class).getAllPermissionsByRole(id, pageable, pageAssembler)) .withSelfRel(); - PagedResources> pagedResources = pageAssembler.toResource(page, link); + PagedModel> pagedResources = pageAssembler.toModel(page, link); return ResponseEntity.ok(pagedResources); } diff --git a/server/src/main/java/com/gms/controller/security/user/RestUserController.java b/server/src/main/java/com/gms/controller/security/user/RestUserController.java index 4e5706d..0aadb48 100644 --- a/server/src/main/java/com/gms/controller/security/user/RestUserController.java +++ b/server/src/main/java/com/gms/controller/security/user/RestUserController.java @@ -6,7 +6,7 @@ import com.gms.util.exception.GmsGeneralException; import lombok.RequiredArgsConstructor; import org.springframework.data.rest.webmvc.BasePathAwareController; -import org.springframework.hateoas.Resource; +import org.springframework.hateoas.EntityModel; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.PostMapping; @@ -37,17 +37,17 @@ public class RestUserController { * controller annotated as {@code @BasePathAwareController}. This method is intended to be used by the Spring * framework and should not be overridden. Doing so may produce unexpected results. * - * @param user {@link EUser} data to be created. + * @param userEntityModel {@link EUser} data to be created. * @return A {@link EUser} mapped into a @{@link ResponseBody}. * @throws GmsGeneralException when an unhandled exception occurs. */ @PostMapping(path = ResourcePath.USER, produces = "application/hal+json") @ResponseStatus(HttpStatus.CREATED) @ResponseBody - public ResponseEntity register(@RequestBody @Valid final Resource user) + public ResponseEntity register(@RequestBody @Valid final EntityModel userEntityModel) throws GmsGeneralException { EUser u = userService.signUp( - user.getContent(), + userEntityModel.getContent(), UserService.EmailStatus.VERIFIED, UserService.RegistrationPrivilege.SUPER_USER ); diff --git a/server/src/main/java/com/gms/domain/security/ownedentity/EOwnedEntity.java b/server/src/main/java/com/gms/domain/security/ownedentity/EOwnedEntity.java index be8256d..6e305e0 100644 --- a/server/src/main/java/com/gms/domain/security/ownedentity/EOwnedEntity.java +++ b/server/src/main/java/com/gms/domain/security/ownedentity/EOwnedEntity.java @@ -3,10 +3,10 @@ import com.gms.domain.GmsEntity; import com.gms.util.constant.SecurityConst; import com.gms.util.i18n.CodeI18N; -import lombok.Data; +import lombok.AllArgsConstructor; import lombok.EqualsAndHashCode; +import lombok.Getter; import lombok.NoArgsConstructor; -import lombok.RequiredArgsConstructor; import lombok.ToString; import javax.persistence.Column; @@ -26,9 +26,9 @@ * @author Asiel Leal Celdeiro | lealceldeiro@gmail.com * @version 0.1 */ -@Data +@Getter +@AllArgsConstructor @NoArgsConstructor(force = true) -@RequiredArgsConstructor @EqualsAndHashCode(callSuper = true) @ToString(exclude = "description") @Entity @@ -46,7 +46,7 @@ public final class EOwnedEntity extends GmsEntity { @NotBlank(message = FIELD_NOT_BLANK) @Size(max = STRING_LENGTH_DEFAULT, message = FIELD_SIZE) @Column(nullable = false) - private final String name; + private String name; /** * A unique string representation of the {@link #name}. Useful when there are other entities with the same @@ -57,7 +57,7 @@ public final class EOwnedEntity extends GmsEntity { @Size(max = STRING_LENGTH_DEFAULT, message = FIELD_SIZE) @Pattern(regexp = SecurityConst.USERNAME_REGEXP, message = CodeI18N.FIELD_PATTERN_INCORRECT_USERNAME) @Column(unique = true, nullable = false) - private final String username; + private String username; /** * A brief description of the entity. @@ -66,6 +66,6 @@ public final class EOwnedEntity extends GmsEntity { @NotBlank(message = CodeI18N.FIELD_NOT_BLANK) @Size(max = STRING_LENGTH_MAX, message = CodeI18N.FIELD_SIZE) @Column(nullable = false, length = STRING_LENGTH_MAX) - private final String description; + private String description; } diff --git a/server/src/main/java/com/gms/domain/security/role/BRole.java b/server/src/main/java/com/gms/domain/security/role/BRole.java index 46680f3..0cba4f5 100644 --- a/server/src/main/java/com/gms/domain/security/role/BRole.java +++ b/server/src/main/java/com/gms/domain/security/role/BRole.java @@ -2,10 +2,12 @@ import com.gms.domain.GmsEntity; import com.gms.domain.security.permission.BPermission; -import lombok.Data; +import lombok.AccessLevel; +import lombok.AllArgsConstructor; import lombok.EqualsAndHashCode; +import lombok.Getter; import lombok.NoArgsConstructor; -import lombok.RequiredArgsConstructor; +import lombok.Setter; import lombok.ToString; import javax.persistence.Column; @@ -33,9 +35,10 @@ * @author Asiel Leal Celdeiro | lealceldeiro@gmail.com * @version 0.1 */ -@Data +@Getter +@Setter @NoArgsConstructor(force = true) -@RequiredArgsConstructor +@AllArgsConstructor @EqualsAndHashCode(callSuper = true, exclude = "permissions") @ToString(of = {"label"}) @Entity @@ -54,7 +57,8 @@ public final class BRole extends GmsEntity { @Size(max = STRING_LENGTH_DEFAULT, message = FIELD_SIZE) @Pattern(regexp = USERNAME_REGEXP, message = FIELD_PATTERN_INCORRECT_USERNAME) @Column(unique = true, nullable = false) - private final String label; + @Setter(AccessLevel.NONE) + private String label; /** * A description of what is this role for. @@ -80,6 +84,15 @@ public final class BRole extends GmsEntity { ) private Set permissions; + /** + * Creates a new {@link BRole} with a label given by parameter. + * + * @param label Label to assign to the new role. + */ + public BRole(final String label) { + this.label = label; + } + /** * Adds a permission p to a role. * diff --git a/server/src/main/java/com/gms/domain/security/user/EUser.java b/server/src/main/java/com/gms/domain/security/user/EUser.java index d70faaa..7085eec 100644 --- a/server/src/main/java/com/gms/domain/security/user/EUser.java +++ b/server/src/main/java/com/gms/domain/security/user/EUser.java @@ -4,10 +4,10 @@ import com.gms.util.i18n.CodeI18N; import lombok.AccessLevel; import lombok.AllArgsConstructor; -import lombok.Data; import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.NoArgsConstructor; +import lombok.Setter; import lombok.ToString; import org.springframework.data.rest.core.annotation.RestResource; import org.springframework.security.core.GrantedAuthority; @@ -26,7 +26,7 @@ import static com.gms.util.constant.PersistenceConstant.STRING_LENGTH_254; import static com.gms.util.constant.PersistenceConstant.STRING_LENGTH_DEFAULT; -import static com.gms.util.constant.PersistenceConstant.STRING_LENGTH_MAX; +import static com.gms.util.constant.PersistenceConstant.STRING_LENGTH_PASSWORD; import static com.gms.util.constant.SecurityConst.USERNAME_REGEXP; import static com.gms.util.i18n.CodeI18N.FIELD_NOT_BLANK; import static com.gms.util.i18n.CodeI18N.FIELD_NOT_NULL; @@ -37,7 +37,8 @@ * @author Asiel Leal Celdeiro | lealceldeiro@gmail.com * @version 0.1 */ -@Data +@Getter +@Setter @NoArgsConstructor(force = true) @AllArgsConstructor @EqualsAndHashCode(callSuper = true, exclude = {"authorities", "password"}) @@ -58,7 +59,8 @@ public class EUser extends GmsEntity implements UserDetails { @NotBlank(message = FIELD_NOT_BLANK) @Pattern(regexp = USERNAME_REGEXP, message = FIELD_PATTERN_INCORRECT_USERNAME) @Column(unique = true, nullable = false) - private final String username; + @Setter(AccessLevel.NONE) + private String username; /** * For emails max length as described at http://www.rfc-editor.org/errata_search.php?rfc=3696&eid=1690 and explained @@ -69,7 +71,8 @@ public class EUser extends GmsEntity implements UserDetails { @NotBlank(message = FIELD_NOT_BLANK) @Email(message = CodeI18N.FIELD_NOT_WELL_FORMED) @Column(unique = true, nullable = false, length = STRING_LENGTH_254) - private final String email; + @Setter(AccessLevel.NONE) + private String email; /** * User's name. @@ -78,25 +81,27 @@ public class EUser extends GmsEntity implements UserDetails { @NotBlank(message = FIELD_NOT_BLANK) @Size(max = STRING_LENGTH_DEFAULT, message = FIELD_SIZE) @Column(nullable = false) - private final String name; + @Setter(AccessLevel.NONE) + private String name; /** * User's last name. */ @NotNull(message = FIELD_NOT_NULL) @NotBlank(message = FIELD_NOT_BLANK) - @Size(max = STRING_LENGTH_DEFAULT, message = CodeI18N.FIELD_SIZE) + @Size(max = STRING_LENGTH_DEFAULT, message = FIELD_SIZE) @Column(nullable = false) - private final String lastName; + @Setter(AccessLevel.NONE) + private String lastName; /** * User's password. */ - @NotNull(message = CodeI18N.FIELD_NOT_NULL) - @NotBlank(message = CodeI18N.FIELD_NOT_BLANK) - @Size(max = STRING_LENGTH_MAX, message = CodeI18N.FIELD_SIZE) + @NotNull(message = FIELD_NOT_NULL) + @NotBlank(message = FIELD_NOT_BLANK) + @Size(max = STRING_LENGTH_PASSWORD, message = FIELD_SIZE) // the bean can actually have a LOT of chars, in database it will be stored as a hashed (a LOT LESSER characters) - @Column(nullable = false, length = STRING_LENGTH_MAX) + @Column(nullable = false, length = STRING_LENGTH_PASSWORD) @RestResource(exported = false) private String password; diff --git a/server/src/main/java/com/gms/repository/security/permission/BPermissionRepository.java b/server/src/main/java/com/gms/repository/security/permission/BPermissionRepository.java index 1c43f4d..ef818b6 100644 --- a/server/src/main/java/com/gms/repository/security/permission/BPermissionRepository.java +++ b/server/src/main/java/com/gms/repository/security/permission/BPermissionRepository.java @@ -128,6 +128,6 @@ Page findByNameEqualsOrLabelEquals( * @return A {@link Page} of {@link BPermission} */ @RestResource(exported = false) - Page findAllByRoles(Set roles, Pageable pageable); + Page findAllByRolesIn(Set roles, Pageable pageable); } diff --git a/server/src/main/java/com/gms/repository/security/role/BRoleRepository.java b/server/src/main/java/com/gms/repository/security/role/BRoleRepository.java index e7a871b..c10ca08 100644 --- a/server/src/main/java/com/gms/repository/security/role/BRoleRepository.java +++ b/server/src/main/java/com/gms/repository/security/role/BRoleRepository.java @@ -59,6 +59,6 @@ public interface BRoleRepository extends PagingAndSortingRepository * @return A {@link Page} of {@link BPermission} */ @RestResource(exported = false) - Page findAllByPermissions(Set permissions, Pageable pageable); + Page findAllByPermissionsIn(Set permissions, Pageable pageable); } diff --git a/server/src/main/java/com/gms/repository/security/user/EUserRepositoryImpl.java b/server/src/main/java/com/gms/repository/security/user/EUserRepositoryImpl.java index 4125a47..779452c 100644 --- a/server/src/main/java/com/gms/repository/security/user/EUserRepositoryImpl.java +++ b/server/src/main/java/com/gms/repository/security/user/EUserRepositoryImpl.java @@ -2,7 +2,7 @@ import com.gms.domain.security.user.EUser; import lombok.RequiredArgsConstructor; -import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.security.crypto.password.PasswordEncoder; import javax.persistence.EntityManager; import javax.persistence.PersistenceContext; @@ -18,9 +18,9 @@ public class EUserRepositoryImpl implements EUserRepositoryCustom { /** - * Instance of {@link BCryptPasswordEncoder}. This bean is provided by the Spring framework dependency manager. + * Instance of {@link PasswordEncoder}. This bean is provided by the Spring framework dependency manager. */ - private final BCryptPasswordEncoder encoder; + private final PasswordEncoder passwordEncoder; /** * Dependency on a container-managed {@link EntityManager} and its associated persistence context. @@ -49,11 +49,11 @@ public S save(final S s) { */ @Override public Iterable saveAll(final Iterable it) { - final Iterator iterator = it.iterator(); - S s; - while (iterator.hasNext()) { - s = iterator.next(); - persist(s); + final Iterator userIterator = it.iterator(); + S user; + while (userIterator.hasNext()) { + user = userIterator.next(); + persist(user); } return it; @@ -66,7 +66,7 @@ public Iterable saveAll(final Iterable it) { */ private void persist(final EUser u) { if (u.getPassword() != null) { - u.setPassword(encoder.encode(u.getPassword())); + u.setPassword(passwordEncoder.encode(u.getPassword())); } entityManager.persist(u); } diff --git a/server/src/main/java/com/gms/repositorydao/BAuthorizationDAO.java b/server/src/main/java/com/gms/repositorydao/BAuthorizationDAO.java index ec50bb4..d6a4442 100644 --- a/server/src/main/java/com/gms/repositorydao/BAuthorizationDAO.java +++ b/server/src/main/java/com/gms/repositorydao/BAuthorizationDAO.java @@ -44,20 +44,21 @@ public abstract class BAuthorizationDAO { */ public abstract List getRolesForUserOverEntity(long userId, long entityId); - final List getRolesListFrom(final Iterable rawVal) { + final List getRolesListFrom(final Iterable resultSet) { final int idIndex = 0; final int versionIndex = 1; final int labelIndex = 2; final int descriptionIndex = 3; final int enabledIndex = 4; - BRole role; + List roles = new LinkedList<>(); - for (Object[] oVal : rawVal) { - role = new BRole(oVal[labelIndex].toString()); - role.setId(Long.valueOf(oVal[idIndex].toString())); - role.setVersion(Integer.valueOf(oVal[versionIndex].toString())); - role.setEnabled(Boolean.valueOf(oVal[enabledIndex].toString())); - role.setDescription(oVal[descriptionIndex].toString()); + + for (Object[] resultSetRoleValue : resultSet) { + final BRole role = new BRole(resultSetRoleValue[labelIndex].toString()); + role.setId(Long.valueOf(resultSetRoleValue[idIndex].toString())); + role.setVersion(Integer.valueOf(resultSetRoleValue[versionIndex].toString())); + role.setEnabled(Boolean.valueOf(resultSetRoleValue[enabledIndex].toString())); + role.setDescription(resultSetRoleValue[descriptionIndex].toString()); roles.add(role); } diff --git a/server/src/main/java/com/gms/service/security/permission/PermissionService.java b/server/src/main/java/com/gms/service/security/permission/PermissionService.java index c45fbcd..ec92a0f 100644 --- a/server/src/main/java/com/gms/service/security/permission/PermissionService.java +++ b/server/src/main/java/com/gms/service/security/permission/PermissionService.java @@ -85,7 +85,7 @@ public Page getAllRolesByPermissionId(final long id, final Pageable pagea Set set = new HashSet<>(); set.add(permission); - return roleRepository.findAllByPermissions(set, pageable); + return roleRepository.findAllByPermissionsIn(set, pageable); } } diff --git a/server/src/main/java/com/gms/service/security/role/RoleService.java b/server/src/main/java/com/gms/service/security/role/RoleService.java index 7194bf6..a577f5e 100644 --- a/server/src/main/java/com/gms/service/security/role/RoleService.java +++ b/server/src/main/java/com/gms/service/security/role/RoleService.java @@ -182,7 +182,7 @@ public Page getAllPermissionsByRoleId(final long id, final Pageable Set set = new HashSet<>(); set.add(role); - return permissionRepository.findAllByRoles(set, pageable); + return permissionRepository.findAllByRolesIn(set, pageable); } public enum ActionOverRolePermissions { diff --git a/server/src/main/java/com/gms/service/security/user/UserService.java b/server/src/main/java/com/gms/service/security/user/UserService.java index 489b48a..89fd213 100644 --- a/server/src/main/java/com/gms/service/security/user/UserService.java +++ b/server/src/main/java/com/gms/service/security/user/UserService.java @@ -118,7 +118,8 @@ public EUser signUp(final EUser u, final EmailStatus emailStatus) { * @param emailStatus One of {@link EmailStatus} which specify whether the email is verified or not. * @param registrationPrivilege One of {@link RegistrationPrivilege} which indicates whether this action is being * performed by a superuser or not. - * @return The registered {@link EUser}'s data + * @return The registered {@link EUser}'s data or {@code null} if the user registration is not allowed and the + * provided {@code registrationPrivilege} is not {@link RegistrationPrivilege#SUPER_USER}. */ public EUser signUp(final EUser u, final EmailStatus emailStatus, final RegistrationPrivilege registrationPrivilege) { diff --git a/server/src/main/java/com/gms/util/constant/DefaultConst.java b/server/src/main/java/com/gms/util/constant/DefaultConst.java index 0d03073..597fa9a 100644 --- a/server/src/main/java/com/gms/util/constant/DefaultConst.java +++ b/server/src/main/java/com/gms/util/constant/DefaultConst.java @@ -2,6 +2,7 @@ import lombok.Getter; import org.springframework.beans.factory.annotation.Value; +import org.springframework.http.HttpHeaders; import org.springframework.stereotype.Component; /** @@ -187,6 +188,6 @@ public class DefaultConst { * * @see DefaultConst#languageHolder */ - public static final String DEFAULT_LANGUAGE_HEADER = "Accept-Language"; + public static final String DEFAULT_LANGUAGE_HEADER = HttpHeaders.ACCEPT_LANGUAGE; //endregion } diff --git a/server/src/main/java/com/gms/util/constant/PersistenceConstant.java b/server/src/main/java/com/gms/util/constant/PersistenceConstant.java index 7ac817d..dab0426 100644 --- a/server/src/main/java/com/gms/util/constant/PersistenceConstant.java +++ b/server/src/main/java/com/gms/util/constant/PersistenceConstant.java @@ -25,6 +25,11 @@ private PersistenceConstant() { /** * Max string length. */ - public static final int STRING_LENGTH_MAX = 10485760; + public static final int STRING_LENGTH_MAX = 10_485_760; + + /** + * Length defined for password string holders.. + */ + public static final int STRING_LENGTH_PASSWORD = 150; } diff --git a/server/src/main/java/com/gms/util/exception/ExceptionUtil.java b/server/src/main/java/com/gms/util/exception/ExceptionUtil.java index 58ef6ae..8906abe 100644 --- a/server/src/main/java/com/gms/util/exception/ExceptionUtil.java +++ b/server/src/main/java/com/gms/util/exception/ExceptionUtil.java @@ -55,7 +55,7 @@ public static Map getResponseBodyForGmsSecurityException(final G additionalData.put("timestamp", System.currentTimeMillis()); additionalData.put("status", HttpStatus.UNAUTHORIZED.value()); additionalData.put("error", msg.getMessage("security.unauthorized")); - additionalData.put("path", (dc.getApiBasePath() + "/" + ex.getPath()).replaceAll("//", "/")); + additionalData.put("path", ex.getPath()); return createResponseBodyAsMap(msg.getMessage(ex.getMessage()), dc, additionalData); } diff --git a/server/src/main/java/com/gms/util/security/token/JWTService.java b/server/src/main/java/com/gms/util/security/token/JWTService.java new file mode 100644 index 0000000..898a460 --- /dev/null +++ b/server/src/main/java/com/gms/util/security/token/JWTService.java @@ -0,0 +1,147 @@ +package com.gms.util.security.token; + +import java.util.Date; +import java.util.Map; + +/** + * Defines how the jwt arte generated. + * + * @author Asiel Leal Celdeiro | lealceldeiro@gmail.com + * @version 0.1 + */ +public interface JWTService { + + /** + * Return the expiration time defined for the access token. If an invalid value was provided, the default one + * (86400s) is used instead. + * + * @return long expiration time. + */ + long getATokenExpirationTime(); + + /** + * Return the expiration time defined for the refresh token. If an invalid value was provided, the default one + * (2592000s) is used instead. + * + * @return long expiration time. + */ + long getRTokenExpirationTime(); + + /** + * Returns json web token with a subject, an expiration time by default, an "issued_at" property, + * a claim with an "expires_in" property signed with a {@link io.jsonwebtoken.SignatureAlgorithm} (HS512). + * + * @param subject Token subject. + * @return {@link String} The token with the information received as parameters. + */ + String createToken(String subject); + + /** + * Returns json web token with a subject, an expiration time, an "issued_at" property, a claim with an "expires_in" + * property signed with a {@link io.jsonwebtoken.SignatureAlgorithm} (HS512). + * + * @param subject Token subject. + * @param expiresIn Expiration time. + * @return {@link String} The token with the information received as parameters. + */ + String createToken(String subject, long expiresIn); + + /** + * Returns json web token with a subject, an authorities, an expiration time by default, an "issued_at" property, + * a claim with an "expires_in" property signed with a {@link io.jsonwebtoken.SignatureAlgorithm} (HS512). + * + * @param subject Token subject. + * @param authorities Token authorities. + * @return {@link String} The token with the information received as parameters. + */ + String createToken(String subject, String authorities); + + /** + * Returns json web token with a subject, an authorities, an expiration time by default, an "issued_at" property, + * a claim with an "expires_in" property signed with a {@link io.jsonwebtoken.SignatureAlgorithm} (HS512). + * This is a convenience method for using instead of generating token using + * {@link JWTService#createToken(String, String, long)} and setting the default expiration time for the refresh + * token. + * + * @param subject Token subject. + * @param authorities Token authorities. + * @return {@link String} The token with the information received as parameters. + */ + String createRefreshToken(String subject, String authorities); + + /** + * Returns json web token with a subject, an authorities, an expiration time, an "issued_at" property, a claim with + * an "expires_in" property signed with a {@link io.jsonwebtoken.SignatureAlgorithm} (HS512). + * + * @param subject Token subject. + * @param authorities Token authorities. + * @param expiresIn An expiration time expressed in milliseconds. + * @return {@link String} The token with the information received as parameters. + */ + String createToken(String subject, String authorities, long expiresIn); + + /** + * Returns a {@link Map} which contains, for every key provided (as a {@code key} param), an entry with the + * claim value. In order to get the value of the claims, the body provided as {@code claimsJwt} param, is parsed. + * The value of every claim is retrieved from the claims using the same key in the {@code key} param. + * + * @param claimsJwt A compact serialized Claim JWT serialized. + * @param key Key to be used in order to get the claim. More than one key can be provided and all of them + * will be used to try to retrieve a new claim under the same key. + * @return Map with all the required information. + */ + Map getClaims(String claimsJwt, String... key); + + /** + * This is a convenience method for generating the map returned when the user logs in or request a new access token. + * + * @param subject The subject set on the jwt. + * @param accessToken The access token generated. + * @param issuedAt Date when the token was issued. + * @param authoritiesString The principal authorities in the format of + * {@code AUTHORITY_NAME-separator-AUTHORITY_NAME} + * where {@code -separator-} is defined in + * {@link com.gms.util.constant.SecurityConst#AUTHORITIES_SEPARATOR}. + * @param refreshToken Refresh token generated in this request. + * @return Map with all this information set under the key defined in {@link com.gms.util.constant.SecurityConst} + * intended for that. + */ + Map createLoginData(String subject, String accessToken, Date issuedAt, String authoritiesString, + String refreshToken); + + /** + * Returns a {@link Map} which contains, for every key provided (as a {@code key} param), an entry with the + * claim value. In order to get the value of the claims, the body provided as {@code claimsJwt} param, is parsed. + * The value of every claim is retrieved from the claims using the same key in the {@code key} param. + * Also extra data such as "sub", "aud", etc, included in the jwt is included. + * + * @param claimsJwt A compact serialized Claim JWT serialized. + * @param key Key to be used in order to get the claim. More than one key can be provided and all of them + * will be used to try to retrieve a new claim under the same key. + * @return Map with all the required information. + * @see io.jsonwebtoken.Claims + */ + Map getClaimsExtended(String claimsJwt, String... key); + + /** + * Returns the key used to specify the value where the token was issued at. + * + * @return String with the corresponding key. + */ + String issuedAtKey(); + + /** + * Returns the key used to specify the value of the token subject. + * + * @return String with the corresponding key. + */ + String subjectKey(); + + /** + * Returns the key used to specify the expiration. + * + * @return String with the corresponding key. + */ + String expirationKey(); + +} diff --git a/server/src/main/java/com/gms/component/security/token/JWTService.java b/server/src/main/java/com/gms/util/security/token/JWTServiceImpl.java similarity index 59% rename from server/src/main/java/com/gms/component/security/token/JWTService.java rename to server/src/main/java/com/gms/util/security/token/JWTServiceImpl.java index 7832539..2d94ce0 100644 --- a/server/src/main/java/com/gms/component/security/token/JWTService.java +++ b/server/src/main/java/com/gms/util/security/token/JWTServiceImpl.java @@ -1,4 +1,4 @@ -package com.gms.component.security.token; +package com.gms.util.security.token; import com.gms.util.GMSRandom; import com.gms.util.constant.SecurityConst; @@ -7,7 +7,7 @@ import io.jsonwebtoken.Jwts; import io.jsonwebtoken.SignatureAlgorithm; import lombok.RequiredArgsConstructor; -import org.springframework.stereotype.Component; +import org.springframework.stereotype.Service; import java.nio.charset.StandardCharsets; import java.util.Date; @@ -22,45 +22,45 @@ * @version 0.2 */ @RequiredArgsConstructor -@Component -public class JWTService { +@Service +final class JWTServiceImpl implements JWTService { /** * Audience key to be used while generating the JWT. */ - public static final String AUDIENCE = Claims.AUDIENCE; + private static final String AUDIENCE = Claims.AUDIENCE; /** * Expiration key to be used while generating the JWT. */ - public static final String EXPIRATION = Claims.EXPIRATION; + private static final String EXPIRATION = Claims.EXPIRATION; /** * ID key to be used while generating the JWT. */ - public static final String ID = Claims.ID; + private static final String ID = Claims.ID; /** * "Issued at" key to be used while generating the JWT. */ - public static final String ISSUED_AT = Claims.ISSUED_AT; + private static final String ISSUED_AT = Claims.ISSUED_AT; /** * "Issuer" key to be used while generating the JWT. */ - public static final String ISSUER = Claims.ISSUER; + private static final String ISSUER = Claims.ISSUER; /** * "Not before" key to be used while generating the JWT. */ - public static final String NOT_BEFORE = Claims.NOT_BEFORE; + private static final String NOT_BEFORE = Claims.NOT_BEFORE; /** * "Subject" key to be used while generating the JWT. */ - public static final String SUBJECT = Claims.SUBJECT; + private static final String SUBJECT = Claims.SUBJECT; /** * Default time to be set for the expiration time of the token. */ - public static final long DEFAULT_ACCESS_TOKEN_EXPIRATION_TIME = 86400000L; + private static final long DEFAULT_ACCESS_TOKEN_EXPIRATION_TIME = 86400000L; /** * Default time to be set for the expiration time of the refresh token. */ - public static final long DEFAULT_REFRESH_TOKEN_EXPIRATION_TIME = 2592000000L; + private static final long DEFAULT_REFRESH_TOKEN_EXPIRATION_TIME = 2592000000L; /** * Instance of {@link SecurityConst}. */ @@ -74,12 +74,6 @@ public class JWTService { */ private static final int THOUSAND = 1000; - /** - * Return the expiration time defined for the access token. If an invalid value was provided, the default one - * (86400s) is used instead. - * - * @return long expiration time. - */ public long getATokenExpirationTime() { // expiration time should come in seconds, that's why the * 1000 and extra-zeros for 86400 seconds return sc.getATokenExpirationTime() > 0 @@ -87,12 +81,6 @@ public long getATokenExpirationTime() { : DEFAULT_ACCESS_TOKEN_EXPIRATION_TIME; // set 1 day if an invalid value was provided } - /** - * Return the expiration time defined for the refresh token. If an invalid value was provided, the default one - * (2592000s) is used instead. - * - * @return long expiration time. - */ public long getRTokenExpirationTime() { // expiration time should come in seconds, that's why the * 1000 and extra-zeros for 2592000 seconds return sc.getRTokenExpirationTime() > 0 @@ -100,79 +88,26 @@ public long getRTokenExpirationTime() { : DEFAULT_REFRESH_TOKEN_EXPIRATION_TIME; // set 30 days if an invalid value was provided } - /** - * Returns json web token with a subject, an expiration time by default, an "issued_at" property, - * a claim with an "expires_in" property signed with a {@link SignatureAlgorithm} (HS512). - * - * @param subject Token subject. - * @return {@link String} The token with the information received as parameters. - */ public String createToken(final String subject) { return getBuilder(subject).compact(); } - /** - * Returns json web token with a subject, an expiration time, an "issued_at" property, a claim with an "expires_in" - * property signed with a {@link SignatureAlgorithm} (HS512). - * - * @param subject Token subject. - * @param expiresIn Expiration time. - * @return {@link String} The token with the information received as parameters. - */ public String createToken(final String subject, final long expiresIn) { return getBuilder(subject, expiresIn).compact(); } - /** - * Returns json web token with a subject, an authorities, an expiration time by default, an "issued_at" property, - * a claim with an "expires_in" property signed with a {@link SignatureAlgorithm} (HS512). - * - * @param subject Token subject. - * @param authorities Token authorities. - * @return {@link String} The token with the information received as parameters. - */ public String createToken(final String subject, final String authorities) { return getBuilder(subject, authorities).compact(); } - /** - * Returns json web token with a subject, an authorities, an expiration time by default, an "issued_at" property, - * a claim with an "expires_in" property signed with a {@link SignatureAlgorithm} (HS512). - * This is a convenience method for using instead of generating token using - * {@link JWTService#createToken(String, String, long)} and setting the default expiration time for the refresh - * token. - * - * @param subject Token subject. - * @param authorities Token authorities. - * @return {@link String} The token with the information received as parameters. - */ public String createRefreshToken(final String subject, final String authorities) { return getBuilder(subject, authorities, getRTokenExpirationTime()).compact(); } - /** - * Returns json web token with a subject, an authorities, an expiration time, an "issued_at" property, a claim with - * an "expires_in" property signed with a {@link SignatureAlgorithm} (HS512). - * - * @param subject Token subject. - * @param authorities Token authorities. - * @param expiresIn An expiration time expressed in milliseconds. - * @return {@link String} The token with the information received as parameters. - */ public String createToken(final String subject, final String authorities, final long expiresIn) { return getBuilder(subject, authorities, expiresIn).compact(); } - /** - * Returns a {@link Map} which contains, for every key provided (as a {@code key} param), an entry with the - * claim value. In order to get the value of the claims, the body provided as {@code claimsJwt} param, is parsed. - * The value of every claim is retrieved from the claims using the same key in the {@code key} param. - * - * @param claimsJwt A compact serialized Claim JWT serialized. - * @param key Key to be used in order to get the claim. More than one key can be provided and all of them - * will be used to try to retrieve a new claim under the same key. - * @return Map with all the required information. - */ public Map getClaims(final String claimsJwt, final String... key) { Map r = new HashMap<>(); processClaimsJWT(claimsJwt, r, key); @@ -180,20 +115,9 @@ public Map getClaims(final String claimsJwt, final String... key return r; } - /** - * This is a convenience method for generating the map returned when the user logs in or request a new access token. - * - * @param subject The subject set on the jwt. - * @param accessToken The access token generated. - * @param issuedAt Date when the token was issued. - * @param authoritiesString The principal authorities in the format of - * {@code AUTHORITY_NAME-separator-AUTHORITY_NAME} - * where {@code -separator-} is defined in {@link SecurityConst#AUTHORITIES_SEPARATOR}. - * @param refreshToken Refresh token generated in this request. - * @return Map with all this information set under the key defined in {@link SecurityConst} intended for that. - */ - public Map createLoginData(final String subject, final String accessToken, final Date issuedAt, - final String authoritiesString, final String refreshToken) { + public Map createLoginData(final String subject, final String accessToken, + final Date issuedAt, final String authoritiesString, + final String refreshToken) { Map returnMap = new HashMap<>(); returnMap.put(SecurityConst.USERNAME_HOLDER, subject); returnMap.put(sc.getATokenHolder(), accessToken); @@ -210,18 +134,6 @@ public Map createLoginData(final String subject, final String ac return returnMap; } - /** - * Returns a {@link Map} which contains, for every key provided (as a {@code key} param), an entry with the - * claim value. In order to get the value of the claims, the body provided as {@code claimsJwt} param, is parsed. - * The value of every claim is retrieved from the claims using the same key in the {@code key} param. - * Also extra data such as "sub", "aud", etc, included in the jwt is included. - * - * @param claimsJwt A compact serialized Claim JWT serialized. - * @param key Key to be used in order to get the claim. More than one key can be provided and all of them - * will be used to try to retrieve a new claim under the same key. - * @return Map with all the required information. - * @see Claims - */ public Map getClaimsExtended(final String claimsJwt, final String... key) { Map r = new HashMap<>(); Claims claims = processClaimsJWT(claimsJwt, r, key); @@ -237,6 +149,21 @@ public Map getClaimsExtended(final String claimsJwt, final Strin return r; } + @Override + public String issuedAtKey() { + return ISSUED_AT; + } + + @Override + public String subjectKey() { + return SUBJECT; + } + + @Override + public String expirationKey() { + return EXPIRATION; + } + private Claims processClaimsJWT(final String claimsJwt, final Map claims, final String... key) { Claims pClaims = Jwts.parser() diff --git a/server/src/main/java/com/gms/component/security/token/package-info.java b/server/src/main/java/com/gms/util/security/token/package-info.java similarity index 64% rename from server/src/main/java/com/gms/component/security/token/package-info.java rename to server/src/main/java/com/gms/util/security/token/package-info.java index 84513af..ca4f673 100644 --- a/server/src/main/java/com/gms/component/security/token/package-info.java +++ b/server/src/main/java/com/gms/util/security/token/package-info.java @@ -1,4 +1,4 @@ /** * This package contains classes which handle authorization tokens. */ -package com.gms.component.security.token; +package com.gms.util.security.token; diff --git a/server/src/main/resources/application.properties b/server/src/main/resources/application.properties index 6fcdc81..b7c8f8d 100644 --- a/server/src/main/resources/application.properties +++ b/server/src/main/resources/application.properties @@ -1,4 +1,4 @@ -#region DB +# region DB spring.datasource.url=jdbc:postgresql://127.0.0.1/gmsdev # user with granted permissions for performing CREATE, UPDATE, SELECT and DELETE queries spring.datasource.username=postgres @@ -11,9 +11,10 @@ spring.jpa.open-in-view=false spring.flyway.locations=classpath:db/migration/{vendor} # user with granted permissions for modifying the schema and performing CREATE, UPDATE, SELECT and DELETE queries spring.flyway.user=postgres -# password for user with granted permissions for modifying the schema and performing CREATE, UPDATE, SELECT and DELETE queries +# password for user with granted permissions for modifying the schema and performing CREATE, UPDATE, SELECT and DELETE spring.flyway.password=postgres spring.flyway.enabled=true + # region disable creation warning # If `spring.flyway.enabled = false` and `spring.jpa.hibernate.ddl-auto = update`, uncomment below lines # more info, see: https://stackoverflow.com/a/50374132/5640649 @@ -22,62 +23,78 @@ spring.flyway.enabled=true # for spring data #spring.jpa.properties.hibernate.schema_update.unique_constraint_strategy=RECREATE_QUIETLY # endregion -#endregion -#region Error Handling +# endregion + +# region Error Handling spring.mvc.throw-exception-if-no-handler-found=true -#endregion -#region Security +# endregion + +# region Security gms.request.auth.username=usernameOrEmail gms.request.auth.password=password -#region JWT -#region General -#Make sure this is a strong secret. A good one may be found at https://www.grc.com/passwords.htm, https://strongpasswordgenerator.com, https://passwordsgenerator.net/ + +# region JWT +# region General +# Make sure this is a strong secret. A good one may be found at https://www.grc.com/passwords.htm, +# https://strongpasswordgenerator.com, https://passwordsgenerator.net/ gms.security.jwt.secret=OIwOG02p4f8UyfqAwEAHnKaEjpwQMyBqO9cmvp70d6P9nbuNbF6c0WQwlYBjWjb gms.security.jwt.issued_time_holder=issued_at gms.security.jwt.authorities_holder=authorities gms.security.jwt.issuer=www.gms.com -#endregion -#region Access Token -# ... as per https://tools.ietf.org/html/rfc6750, gms.security.jwt.token_holder and gms.security.jwt.token_type properties should not be customised. +# endregion + +# region Access Token +# as per https://tools.ietf.org/html/rfc6750, gms.security.jwt.token_holder and gms.security.jwt.token_type +# properties should not be customised. gms.security.jwt.token_holder=access_token gms.security.jwt.token_type=Bearer gms.security.jwt.token_type_holder=token_type gms.security.jwt.token_header=Authorization gms.security.jwt.token_header_to_be_sent_holder=header_to_be_sent -# ... a positive long(https://docs.oracle.com/javase/7/docs/api/java/lang/Long.html) value in seconds (1 day by default) -# by default, 1 day (in seconds) +# a positive long(https://docs.oracle.com/javase/7/docs/api/java/lang/Long.html) value in seconds (1 day by default) gms.security.jwt.token_expiration=86400 gms.security.jwt.token_expiration_time_holder=token_expiration_time gms.security.jwt.token_expires_in_holder=token_expires_in -#endregion -#region Refresh Token +# endregion + +# region Refresh Token gms.security.jwt.refresh_token_holder=refresh_token -# ... a positive long(https://docs.oracle.com/javase/7/docs/api/java/lang/Long.html) value in seconds (30 days by default) -# by default, 30 days (in seconds) +# a positive long(https://docs.oracle.com/javase/7/docs/api/java/lang/Long.html) value in seconds (30 days by default) gms.security.jwt.refresh_token_expiration=2592000 gms.security.jwt.refresh_token_expiration_time_holder=refresh_token_expiration_time gms.security.jwt.refresh_token_expires_in_holder=refresh_token_expires_in -#endregion -#endregion -#region Sign-Up/Sign-In/Sign-Out +# endregion +# endregion + +# region Sign-Up/Sign-In/Sign-Out gms.security.sign_up_url=/sign-up gms.security.sign_in_url=/login -#endregion +# endregion + # semicolon-separated url # relative url to base-api-path gms.security.free_url_any= gms.security.free_url_post= gms.security.free_url_get= -#endregion -#region Config -spring.jackson.default-property-inclusion=non-null -spring.data.rest.basePath=/api +# endregion + +# region Config +logging.file.path=/home/gms/logs +server.servlet.jsp.registered=false spring.application.name=gms +spring.data.rest.basePath=/api spring.http.encoding.charset=UTF-8 -logging.path=/home/gms/logs -server.port=80 -#endregion +spring.jackson.default-property-inclusion=non_null +spring.messages.basename=i18n.configuration,i18n.entity,i18n.field,i18n.frameworkoverride,i18n.label,i18n.messages,\ + i18n.role,i18n.user,i18n.validations +spring.messages.encoding=UTF-8 +spring.messages.use-code-as-default-message=true +spring.messages.fallback-to-system-locale=false +spring.mvc.hiddenmethod.filter.enabled=false +# endregion + # Includes spring.profiles.include=misc,vars,initial + # Active profile (development, test, production): change for required env -spring.profiles.active=development \ No newline at end of file +spring.profiles.active=development diff --git a/server/src/main/resources/config/application-development.properties b/server/src/main/resources/config/application-development.properties index 4a764ee..aec85e5 100644 --- a/server/src/main/resources/config/application-development.properties +++ b/server/src/main/resources/config/application-development.properties @@ -1,7 +1,11 @@ server.port=8081 -#region DB + +# region DB spring.jpa.show-sql=true -#endregion +# endregion + # region Miscellaneous gms.application.env=Development -#endregion \ No newline at end of file +# endregion + +logging.level.root=debug diff --git a/server/src/main/resources/config/application-misc.properties b/server/src/main/resources/config/application-misc.properties index 36f90d5..fd03a96 100644 --- a/server/src/main/resources/config/application-misc.properties +++ b/server/src/main/resources/config/application-misc.properties @@ -1,3 +1,2 @@ # Miscellaneous -gms.application.version=0.0.1 -gms.angular.version=5.x \ No newline at end of file +gms.application.version=0.0.2 \ No newline at end of file diff --git a/server/src/main/resources/config/application-production.properties b/server/src/main/resources/config/application-production.properties index a8c880a..5677896 100644 --- a/server/src/main/resources/config/application-production.properties +++ b/server/src/main/resources/config/application-production.properties @@ -1,6 +1,7 @@ -#region DB +# region DB spring.datasource.url=jdbc:postgresql://127.0.0.1/gms -#endregion -#region Miscellaneous +# endregion + +# region Miscellaneous gms.application.env=Production -#endregion \ No newline at end of file +# endregion \ No newline at end of file diff --git a/server/src/main/resources/config/application-test.properties b/server/src/main/resources/config/application-test.properties index a258a53..5b24148 100644 --- a/server/src/main/resources/config/application-test.properties +++ b/server/src/main/resources/config/application-test.properties @@ -1,9 +1,10 @@ -#region DB +# region DB spring.datasource.url=jdbc:postgresql://127.0.0.1/gmstest spring.datasource.username=postgres spring.datasource.password=postgres spring.datasource.driver-class-name=org.postgresql.Driver -#endregion -#region Miscellaneous +# endregion + +# region Miscellaneous gms.application.env=Test -#endregion +# endregion diff --git a/server/src/main/resources/config/application-vars.properties b/server/src/main/resources/config/application-vars.properties index 299d180..d54acab 100644 --- a/server/src/main/resources/config/application-vars.properties +++ b/server/src/main/resources/config/application-vars.properties @@ -10,6 +10,7 @@ spring.data.rest.sort-param-name=sort # Name of the URL query string parameter that indicates how many results to return at once. spring.data.rest.limit-param-name=size # endregion + gms.i18n.lang.holder=lang gms.i18n.lang.default=en gms.response.message=message diff --git a/server/src/main/resources/db/migration/postgresql/V0__Create_tables.sql b/server/src/main/resources/db/migration/postgresql/V0__Create_tables.sql index c9bae41..38cb470 100644 --- a/server/src/main/resources/db/migration/postgresql/V0__Create_tables.sql +++ b/server/src/main/resources/db/migration/postgresql/V0__Create_tables.sql @@ -1,26 +1,26 @@ /* * BConfiguration */ -CREATE TABLE bconfiguration ( +CREATE TABLE IF NOT EXISTS bconfiguration ( id int8 NOT NULL , version int4, key VARCHAR(255) NOT NULL, user_id int8, value VARCHAR(255) NOT NULL, - PRIMARY KEY (id) + CONSTRAINT BCONFIGURATION_PK PRIMARY KEY (id) ); /* * BPermission */ -CREATE TABLE bpermission ( +CREATE TABLE IF NOT EXISTS bpermission ( id int8 NOT NULL, version int4, label VARCHAR(255) NOT NULL, name VARCHAR(255) NOT NULL, - PRIMARY KEY (id) + CONSTRAINT BPERMISSION_PK PRIMARY KEY (id), + CONSTRAINT BPERMISSION_LABEL_UK UNIQUE (label), + CONSTRAINT BPERMISSION_NAME_UK UNIQUE (name) ); -ALTER TABLE IF EXISTS bpermission ADD CONSTRAINT UK_BPERMISSION_LABEL UNIQUE (label); -ALTER TABLE IF EXISTS bpermission ADD CONSTRAINT UK_BPERMISSION_NAME UNIQUE (name); /* * BRole @@ -31,9 +31,9 @@ CREATE TABLE brole ( description VARCHAR(10485760), enabled BOOLEAN, label VARCHAR(255) NOT NULL, - PRIMARY KEY (id) + CONSTRAINT BROLE_PK PRIMARY KEY (id), + CONSTRAINT BROLE_LABEL_UK UNIQUE (label) ); -ALTER TABLE IF EXISTS brole ADD CONSTRAINT UK_BROLE_LABEL UNIQUE (label); /* * BRole - BPermission @@ -41,10 +41,10 @@ ALTER TABLE IF EXISTS brole ADD CONSTRAINT UK_BROLE_LABEL UNIQUE (label); CREATE TABLE brole_bpermission ( brole_id int8 NOT NULL, bpermission_id int8 NOT NULL, - PRIMARY KEY (brole_id, bpermission_id) + CONSTRAINT BROLE_PERMISSION_PK PRIMARY KEY (brole_id, bpermission_id), + CONSTRAINT BPERMISSION_BRP_FK FOREIGN KEY (bpermission_id) REFERENCES bpermission, + CONSTRAINT BROLE_BRP_FK FOREIGN KEY (brole_id) REFERENCES brole ); -ALTER TABLE IF EXISTS brole_bpermission ADD CONSTRAINT FK_BPERMISSION_BRP FOREIGN KEY (bpermission_id) REFERENCES bpermission; -ALTER TABLE IF EXISTS brole_bpermission ADD CONSTRAINT FK_BROLE_BRP FOREIGN KEY (brole_id) REFERENCES brole; /* * EUser @@ -61,12 +61,12 @@ CREATE TABLE euser ( enabled BOOLEAN, last_name VARCHAR(255) NOT NULL, name VARCHAR(255) NOT NULL, - password VARCHAR(10485760) NOT NULL, + password VARCHAR(150) NOT NULL, username VARCHAR(255) NOT NULL, - PRIMARY KEY (id) + CONSTRAINT USER_PK PRIMARY KEY (id), + CONSTRAINT EUSER_EMAIL_UK UNIQUE (email), + CONSTRAINT EUSER_USERNAME_UK UNIQUE (username) ); -ALTER TABLE IF EXISTS euser ADD CONSTRAINT UK_EUSER_EMAIL UNIQUE (email); -ALTER TABLE IF EXISTS euser ADD CONSTRAINT UK_EUSER_USERNAME UNIQUE (username); /* * EOwnedEntity @@ -77,9 +77,9 @@ CREATE TABLE eowned_entity ( description VARCHAR(10485760) NOT NULL, name VARCHAR(255) NOT NULL, username VARCHAR(255) NOT NULL, - PRIMARY KEY (id) + CONSTRAINT EOWNED_ENTITY_PK PRIMARY KEY (id), + CONSTRAINT EOWNED_ENTITY_USERNAME_UK UNIQUE (username) ); -ALTER TABLE IF EXISTS eowned_entity ADD CONSTRAINT UK_EOWNED_ENTITY_USERNAME UNIQUE (username); /** * BAuthorization @@ -88,11 +88,11 @@ CREATE TABLE bauthorization ( entity_id int8 NOT NULL, role_id int8 NOT NULL, user_id int8 NOT NULL, - PRIMARY KEY (entity_id, role_id, user_id) + CONSTRAINT BAUTHORIZATION_PK PRIMARY KEY (entity_id, role_id, user_id), + CONSTRAINT USER_BAUTH_FK FOREIGN KEY (user_id) REFERENCES euser, + CONSTRAINT EOWNEDENTITY_BAUTH_FK FOREIGN KEY (entity_id) REFERENCES eowned_entity, + CONSTRAINT BROLE_BAUTH_FK FOREIGN KEY (role_id) REFERENCES brole ); -ALTER TABLE IF EXISTS bauthorization ADD CONSTRAINT FK_EUSER_BAUTH FOREIGN KEY (user_id) REFERENCES euser; -ALTER TABLE IF EXISTS bauthorization ADD CONSTRAINT FK_EOWNEDENTITY_BAUTH FOREIGN KEY (entity_id) REFERENCES eowned_entity; -ALTER TABLE IF EXISTS bauthorization ADD CONSTRAINT FK_BROLE_BAUTH FOREIGN KEY (role_id) REFERENCES brole; /** * Hibernate sequence diff --git a/server/src/main/resources/i18n/configuration_es.properties b/server/src/main/resources/i18n/configuration_es.properties index de3f0df..0c56213 100644 --- a/server/src/main/resources/i18n/configuration_es.properties +++ b/server/src/main/resources/i18n/configuration_es.properties @@ -1,2 +1,2 @@ config.not.found=Configuración no encontrada. -config.param.user.not.valid=El parámetro usuario debe ser un número valido (el identificador de un usuario). \ No newline at end of file +config.param.user.not.valid=El parámetro usuario debe ser un número válido (el identificador de un usuario). \ No newline at end of file diff --git a/server/src/main/resources/i18n/frameworkoverride.properties b/server/src/main/resources/i18n/frameworkoverride.properties index 842fdc2..74d7b38 100644 --- a/server/src/main/resources/i18n/frameworkoverride.properties +++ b/server/src/main/resources/i18n/frameworkoverride.properties @@ -1,7 +1,7 @@ AbstractAccessDecisionManager.accessDenied=Access denied. AbstractSecurityInterceptor.authenticationNotFound=User not found. AbstractUserDetailsAuthenticationProvider.badCredentials=Bad credentials. -AbstractUserDetailsAuthenticationProvider.credentialsExpired=Credentilas expired. +AbstractUserDetailsAuthenticationProvider.credentialsExpired=Credentials expired. AbstractUserDetailsAuthenticationProvider.disabled=User deactivated. AbstractUserDetailsAuthenticationProvider.expired=User account expired. AbstractUserDetailsAuthenticationProvider.locked=User locked. diff --git a/server/src/test/java/com/gms/ApplicationTest.java b/server/src/test/java/com/gms/ApplicationTest.java index a3fad54..2f8dbb7 100644 --- a/server/src/test/java/com/gms/ApplicationTest.java +++ b/server/src/test/java/com/gms/ApplicationTest.java @@ -60,9 +60,9 @@ public void commandLineRunnerBeanCreationIsOK() { * Test to be executed by JUnit. */ @Test - public void bCryptPasswordEncoderTest() { + public void passwordEncoderTest() { Application app = new Application(); - assertNotNull(app.bCryptPasswordEncoder()); + assertNotNull(app.gmsPasswordEncoder()); } } diff --git a/server/src/test/java/com/gms/component/security/authentication/AuthenticationFacadeImplTest.java b/server/src/test/java/com/gms/component/security/authentication/AuthenticationFacadeImplTest.java index 4365f26..3d82dd4 100644 --- a/server/src/test/java/com/gms/component/security/authentication/AuthenticationFacadeImplTest.java +++ b/server/src/test/java/com/gms/component/security/authentication/AuthenticationFacadeImplTest.java @@ -1,6 +1,7 @@ package com.gms.component.security.authentication; import com.gms.Application; +import com.gms.config.security.authentication.AuthenticationFacade; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; diff --git a/server/src/test/java/com/gms/config/locale/LocaleConfigTest.java b/server/src/test/java/com/gms/config/locale/LocaleConfigTest.java new file mode 100644 index 0000000..a2f0817 --- /dev/null +++ b/server/src/test/java/com/gms/config/locale/LocaleConfigTest.java @@ -0,0 +1,175 @@ +package com.gms.config.locale; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.gms.Application; +import com.gms.domain.security.ownedentity.EOwnedEntity; +import com.gms.domain.security.user.EUser; +import com.gms.repository.security.ownedentity.EOwnedEntityRepository; +import com.gms.repository.security.user.EUserRepository; +import com.gms.service.AppService; +import com.gms.testutil.EntityUtil; +import com.gms.testutil.GmsMockUtil; +import com.gms.testutil.GmsSecurityUtil; +import com.gms.testutil.RestDoc; +import com.gms.util.constant.DefaultConst; +import com.gms.util.constant.ResourcePath; +import com.gms.util.constant.SecurityConst; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.http.MediaType; +import org.springframework.restdocs.JUnitRestDocumentation; +import org.springframework.restdocs.mockmvc.RestDocumentationResultHandler; +import org.springframework.security.web.FilterChainProxy; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.web.context.WebApplicationContext; + +import static org.junit.Assert.assertTrue; +import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.delete; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = Application.class) +public class LocaleConfigTest { + + /** + * Instance of {@link JUnitRestDocumentation} to create the documentation for Asciidoc from the resutls of the + * mocked webrequests. + */ + @Rule + public final JUnitRestDocumentation restDocumentation = new JUnitRestDocumentation(RestDoc.APIDOC_LOCATION); + + /** + * Instance of {@link WebApplicationContext}. + */ + @Autowired + private WebApplicationContext context; + /** + * Instance of {@link ObjectMapper}. + */ + private final ObjectMapper objectMapper = GmsSecurityUtil.getObjectMapper(); + + /** + * Instance of {@link FilterChainProxy}. + */ + @Autowired + private FilterChainProxy springSecurityFilterChain; + + /** + * Instance of {@link SecurityConst}. + */ + @Autowired + private SecurityConst sc; + /** + * Instance of {@link DefaultConst}. + */ + @Autowired + private DefaultConst dc; + + /** + * Instance of {@link AppService}. + */ + @Autowired + private AppService appService; + /** + * Instance of {@link EUserRepository}. + */ + @Autowired + private EUserRepository userRepository; + /** + * Instance of {@link EOwnedEntityRepository}. + */ + @Autowired + private EOwnedEntityRepository entityRepository; + + /** + * Instance of {@link MockMvc} to perform web requests. + */ + private MockMvc mvc; + + /** + * An instance of {@link RestDocumentationResultHandler} for the documenting RESTful APIs endpoints. + */ + private final RestDocumentationResultHandler restDocResHandler = RestDoc.getRestDocumentationResultHandler(); + + /** + * Instance of {@link EUser}. + */ + private EUser user; + /** + * An instance of {@link EOwnedEntity}. + */ + private EOwnedEntity entity; + + // region vars + /** + * API request URL. + */ + private String url; + /** + * Header to be used for sending authentication credentials. + */ + private String authHeader; + /** + * Type of the authorization token. + */ + private String tokenType; + /** + * Access token used to get access to secured resources. + */ + private String accessToken; + // endregion + + /** + * Sets up the tests resources. + */ + @Before + public void setUp() throws Exception { + assertTrue("Application initial configuration failed", appService.isInitialLoadOK()); + + mvc = GmsMockUtil.getMvcMock(context, restDocumentation, restDocResHandler, springSecurityFilterChain); + + url = dc.getApiBasePath() + "/" + ResourcePath.USER + "/roles/{userId}/{entityId}"; + authHeader = sc.getATokenHeader(); + tokenType = sc.getATokenType(); + + accessToken = GmsSecurityUtil.createSuperAdminAuthToken(dc, sc, mvc, objectMapper, false); + } + + /** + * Test to be executed by JUnit. + */ + @Test + public void deleteRolesEN() throws Exception { + user = userRepository.save(EntityUtil.getSampleUser()); + entity = entityRepository.save(EntityUtil.getSampleEntity()); + + mvc.perform(delete(url, user.getId(), entity.getId()) + .contentType(MediaType.APPLICATION_JSON) + .header(authHeader, tokenType + " " + accessToken) + .content(objectMapper.writeValueAsString(new int[]{-1})) + .header(DefaultConst.DEFAULT_LANGUAGE_HEADER, "en") + ).andExpect(status().isNotFound()); + } + + /** + * Test to be executed by JUnit. + */ + @Test + public void deleteRolesES() throws Exception { + user = userRepository.save(EntityUtil.getSampleUser()); + entity = entityRepository.save(EntityUtil.getSampleEntity()); + + mvc.perform(delete(url, user.getId(), entity.getId()) + .contentType(MediaType.APPLICATION_JSON) + .header(authHeader, tokenType + " " + accessToken) + .param(dc.getLanguageHolder(), "es") + .content(objectMapper.writeValueAsString(new int[]{-1})) + ).andExpect(status().isNotFound()); + } + +} diff --git a/server/src/test/java/com/gms/config/locale/package-info.java b/server/src/test/java/com/gms/config/locale/package-info.java new file mode 100644 index 0000000..e234245 --- /dev/null +++ b/server/src/test/java/com/gms/config/locale/package-info.java @@ -0,0 +1,7 @@ +/** + * This package contains tests for the locale configuration-related components. + * + * @author Asiel Leal Celdeiro | lealceldeiro@gmail.com + * @version 0.1 + */ +package com.gms.config.locale; diff --git a/server/src/test/java/com/gms/config/security/SecurityConfigTest.java b/server/src/test/java/com/gms/config/security/SecurityConfigTest.java index 9e66244..36b2ff9 100644 --- a/server/src/test/java/com/gms/config/security/SecurityConfigTest.java +++ b/server/src/test/java/com/gms/config/security/SecurityConfigTest.java @@ -2,8 +2,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.gms.Application; -import com.gms.component.security.authentication.AuthenticationFacade; -import com.gms.component.security.token.JWTService; +import com.gms.config.security.authentication.AuthenticationFacade; import com.gms.domain.security.ownedentity.EOwnedEntity; import com.gms.domain.security.role.BRole; import com.gms.domain.security.user.EUser; @@ -22,6 +21,7 @@ import com.gms.util.constant.SecurityConst; import com.gms.util.exception.domain.NotFoundEntityException; import com.gms.util.i18n.MessageResolver; +import com.gms.util.security.token.JWTService; import org.junit.Before; import org.junit.Rule; import org.junit.Test; diff --git a/server/src/test/java/com/gms/controller/DefaultControllerAdviceTest.java b/server/src/test/java/com/gms/controller/DefaultControllerAdviceTest.java index d902b23..e646cad 100644 --- a/server/src/test/java/com/gms/controller/DefaultControllerAdviceTest.java +++ b/server/src/test/java/com/gms/controller/DefaultControllerAdviceTest.java @@ -24,7 +24,7 @@ import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.hateoas.Resource; +import org.springframework.hateoas.EntityModel; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.mock.web.MockHttpServletResponse; @@ -206,8 +206,8 @@ private void checkResult(final MvcResult mvcResult) throws UnsupportedEncodingEx ); assertEquals( "Paths do not match.", - res.getString("path"), - dc.getApiBasePath() + "/" + SecurityConst.ACCESS_TOKEN_URL + SecurityConst.ACCESS_TOKEN_URL, + res.getString("path") ); } @@ -229,7 +229,7 @@ public void handleGmsGeneralException() throws Exception { configService.setUserRegistrationAllowed(false); } - Resource resource = getSampleUserResource(); + EntityModel resource = getSampleUserResource(); final MockHttpServletResponse result = mvc.perform( post(apiPrefix + sc.getSignUpUrl()).contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(resource)) @@ -263,7 +263,7 @@ public void handleTransactionSystemException() throws Exception { final String r = random.nextString(); EUser u = new EUser(null, "a" + r + EXAMPLE_EMAIL, EXAMPLE_NAME + r, EXAMPLE_LAST_NAME, EXAMPLE_PASSWORD); - Resource resource = new Resource<>(u); + EntityModel resource = new EntityModel<>(u); mvc.perform( post(apiPrefix + sc.getSignUpUrl()).contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(resource)) @@ -287,7 +287,7 @@ public void handleDataIntegrityViolationException() throws Exception { } final String r = random.nextString(); - Resource resource = getSampleUserResource(r); + EntityModel resource = getSampleUserResource(r); mvc.perform( post(apiPrefix + sc.getSignUpUrl()).contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(resource)) diff --git a/server/src/test/java/com/gms/controller/security/SecurityControllerTest.java b/server/src/test/java/com/gms/controller/security/SecurityControllerTest.java index f802821..3696142 100644 --- a/server/src/test/java/com/gms/controller/security/SecurityControllerTest.java +++ b/server/src/test/java/com/gms/controller/security/SecurityControllerTest.java @@ -23,14 +23,13 @@ import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.hateoas.Resource; +import org.springframework.hateoas.EntityModel; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.restdocs.JUnitRestDocumentation; import org.springframework.restdocs.mockmvc.RestDocumentationResultHandler; import org.springframework.security.web.FilterChainProxy; import org.springframework.test.context.junit4.SpringRunner; -import org.springframework.test.util.ReflectionTestUtils; import org.springframework.test.web.servlet.MockMvc; import org.springframework.web.context.WebApplicationContext; @@ -150,8 +149,7 @@ public void signUp() throws Exception { EUser u = EntityUtil.getSampleUser(r); u.setEnabled(false); - Resource resource = new Resource<>(u); - ReflectionTestUtils.setField(resource, "links", null); + EntityModel resource = new EntityModel<>(u); final ConstrainedFields fields = new ConstrainedFields(EUser.class); @@ -193,7 +191,7 @@ public void signUpKO() throws Exception { if (initial) { configService.setUserRegistrationAllowed(false); } - Resource resource = getSampleUserResource(random.nextString()); + EntityModel resource = getSampleUserResource(random.nextString()); mvc.perform( post(apiPrefix + sc.getSignUpUrl()).contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(resource)) @@ -258,7 +256,7 @@ private void testRefreshTokenKO(final String refreshTokenArg) throws Exception { assertEquals(temp, msg.getMessage("security.unauthorized")); temp = json.getString("path"); - assertEquals(temp, dc.getApiBasePath() + "/" + SecurityConst.ACCESS_TOKEN_URL); + assertEquals(SecurityConst.ACCESS_TOKEN_URL, temp); temp = json.getString(dc.getResMessageHolder()); diff --git a/server/src/test/java/com/gms/controller/security/ownedentity/RestOwnedEntityControllerTest.java b/server/src/test/java/com/gms/controller/security/ownedentity/RestOwnedEntityControllerTest.java index 1c471c6..141ac24 100644 --- a/server/src/test/java/com/gms/controller/security/ownedentity/RestOwnedEntityControllerTest.java +++ b/server/src/test/java/com/gms/controller/security/ownedentity/RestOwnedEntityControllerTest.java @@ -21,7 +21,7 @@ import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.hateoas.Resource; +import org.springframework.hateoas.EntityModel; import org.springframework.http.MediaType; import org.springframework.restdocs.JUnitRestDocumentation; import org.springframework.restdocs.mockmvc.RestDocumentationResultHandler; @@ -211,7 +211,7 @@ public void handleTransactionSystemException() throws Exception { final String r = random.nextString(); EOwnedEntity e = new EOwnedEntity(null, StringUtil.EXAMPLE_USERNAME + r, StringUtil.EXAMPLE_DESCRIPTION + r); - Resource resource = new Resource<>(e); + EntityModel resource = new EntityModel<>(e); mvc.perform( post(apiPrefix + "/" + ResourcePath.OWNED_ENTITY) .contentType(MediaType.APPLICATION_JSON) @@ -237,7 +237,7 @@ public void handleDataIntegrityViolationException() throws Exception { } final String r = random.nextString(); - Resource resource = EntityUtil.getSampleEntityResource(r); + EntityModel resource = EntityUtil.getSampleEntityResource(r); mvc.perform( post(apiPrefix + "/" + ResourcePath.OWNED_ENTITY) .contentType(MediaType.APPLICATION_JSON) diff --git a/server/src/test/java/com/gms/controller/security/user/RestUserControllerTest.java b/server/src/test/java/com/gms/controller/security/user/RestUserControllerTest.java index 7720d78..4def6b7 100644 --- a/server/src/test/java/com/gms/controller/security/user/RestUserControllerTest.java +++ b/server/src/test/java/com/gms/controller/security/user/RestUserControllerTest.java @@ -20,13 +20,12 @@ import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.hateoas.Resource; +import org.springframework.hateoas.EntityModel; import org.springframework.http.MediaType; import org.springframework.restdocs.JUnitRestDocumentation; import org.springframework.restdocs.mockmvc.RestDocumentationResultHandler; import org.springframework.security.web.FilterChainProxy; import org.springframework.test.context.junit4.SpringRunner; -import org.springframework.test.util.ReflectionTestUtils; import org.springframework.test.web.servlet.MockMvc; import org.springframework.web.context.WebApplicationContext; @@ -141,8 +140,7 @@ public void setUp() throws Exception { public void create() throws Exception { final String r = random.nextString(); EUser u = EntityUtil.getSampleUser(r); - Resource resource = new Resource<>(u); - ReflectionTestUtils.setField(resource, "links", null); + EntityModel resource = new EntityModel<>(u); ConstrainedFields fields = new ConstrainedFields(EUser.class); @@ -176,7 +174,7 @@ public void handleTransactionSystemException() throws Exception { String r = random.nextString(); EUser u = new EUser(null, "a" + r + EXAMPLE_EMAIL, EXAMPLE_NAME + r, EXAMPLE_LAST_NAME, EXAMPLE_PASSWORD); - Resource resource = new Resource<>(u); + EntityModel resource = new EntityModel<>(u); mvc.perform( post(apiPrefix + "/" + ResourcePath.USER).contentType(MediaType.APPLICATION_JSON) .header(authHeader, tokenType + " " + accessToken) @@ -190,7 +188,7 @@ public void handleTransactionSystemException() throws Exception { @Test public void handleDataIntegrityViolationException() throws Exception { String r = random.nextString(); - Resource resource = EntityUtil.getSampleUserResource(r); + EntityModel resource = EntityUtil.getSampleUserResource(r); mvc.perform( post(apiPrefix + "/" + ResourcePath.USER).contentType(MediaType.APPLICATION_JSON) .header(authHeader, tokenType + " " + accessToken) diff --git a/server/src/test/java/com/gms/domain/GmsEntityTest.java b/server/src/test/java/com/gms/domain/GmsEntityTest.java index a1cfb96..5bef44d 100644 --- a/server/src/test/java/com/gms/domain/GmsEntityTest.java +++ b/server/src/test/java/com/gms/domain/GmsEntityTest.java @@ -1,10 +1,6 @@ package com.gms.domain; -import com.gms.Application; import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.test.context.junit4.SpringRunner; import org.springframework.test.util.ReflectionTestUtils; import static org.junit.Assert.assertEquals; @@ -14,8 +10,6 @@ * @author Asiel Leal Celdeiro | lealceldeiro@gmail.com * @version 0.1 */ -@RunWith(SpringRunner.class) -@SpringBootTest(classes = Application.class) public class GmsEntityTest { /** diff --git a/server/src/test/java/com/gms/domain/configuration/BConfigurationTest.java b/server/src/test/java/com/gms/domain/configuration/BConfigurationTest.java index 9ab8515..7633b4d 100644 --- a/server/src/test/java/com/gms/domain/configuration/BConfigurationTest.java +++ b/server/src/test/java/com/gms/domain/configuration/BConfigurationTest.java @@ -1,13 +1,9 @@ package com.gms.domain.configuration; -import com.gms.Application; import com.gms.testutil.StringUtil; import com.gms.testutil.validation.PersistenceValidation; import com.gms.util.i18n.CodeI18N; import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.test.context.junit4.SpringRunner; import org.springframework.test.util.ReflectionTestUtils; import static org.junit.Assert.assertEquals; @@ -18,8 +14,6 @@ * @author Asiel Leal Celdeiro | lealceldeiro@gmail.com * @version 0.1 */ -@RunWith(SpringRunner.class) -@SpringBootTest(classes = Application.class) public class BConfigurationTest { /** diff --git a/server/src/test/java/com/gms/domain/security/BAuthorizationTest.java b/server/src/test/java/com/gms/domain/security/BAuthorizationTest.java index 5c4d160..03b3aa6 100644 --- a/server/src/test/java/com/gms/domain/security/BAuthorizationTest.java +++ b/server/src/test/java/com/gms/domain/security/BAuthorizationTest.java @@ -1,15 +1,11 @@ package com.gms.domain.security; -import com.gms.Application; import com.gms.domain.security.ownedentity.EOwnedEntity; import com.gms.domain.security.role.BRole; import com.gms.domain.security.user.EUser; import com.gms.testutil.EntityUtil; import org.junit.Before; import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.test.context.junit4.SpringRunner; import org.springframework.test.util.ReflectionTestUtils; import static org.junit.Assert.assertEquals; @@ -19,8 +15,6 @@ * @author Asiel Leal Celdeiro | lealceldeiro@gmail.com * @version 0.1 */ -@RunWith(SpringRunner.class) -@SpringBootTest(classes = Application.class) public class BAuthorizationTest { /** diff --git a/server/src/test/java/com/gms/domain/security/ownedentity/EOwnedEntityTest.java b/server/src/test/java/com/gms/domain/security/ownedentity/EOwnedEntityTest.java index 00bfae4..84b602b 100644 --- a/server/src/test/java/com/gms/domain/security/ownedentity/EOwnedEntityTest.java +++ b/server/src/test/java/com/gms/domain/security/ownedentity/EOwnedEntityTest.java @@ -1,14 +1,10 @@ package com.gms.domain.security.ownedentity; -import com.gms.Application; import com.gms.testutil.EntityUtil; import com.gms.testutil.StringUtil; import com.gms.testutil.validation.PersistenceValidation; import com.gms.util.i18n.CodeI18N; import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.test.context.junit4.SpringRunner; import org.springframework.test.util.ReflectionTestUtils; import javax.validation.ConstraintViolation; @@ -22,8 +18,6 @@ * @author Asiel Leal Celdeiro | lealceldeiro@gmail.com * @version 0.1 */ -@RunWith(SpringRunner.class) -@SpringBootTest(classes = Application.class) public class EOwnedEntityTest { /** diff --git a/server/src/test/java/com/gms/domain/security/permission/BPermissionTest.java b/server/src/test/java/com/gms/domain/security/permission/BPermissionTest.java index e2a4c2b..43415fa 100644 --- a/server/src/test/java/com/gms/domain/security/permission/BPermissionTest.java +++ b/server/src/test/java/com/gms/domain/security/permission/BPermissionTest.java @@ -1,6 +1,5 @@ package com.gms.domain.security.permission; -import com.gms.Application; import com.gms.domain.security.role.BRole; import com.gms.testutil.EntityUtil; import com.gms.testutil.StringUtil; @@ -8,9 +7,6 @@ import com.gms.util.i18n.CodeI18N; import org.junit.Before; import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.test.context.junit4.SpringRunner; import org.springframework.test.util.ReflectionTestUtils; import javax.validation.ConstraintViolation; @@ -25,8 +21,6 @@ * @author Asiel Leal Celdeiro | lealceldeiro@gmail.com * @version 0.1 */ -@RunWith(SpringRunner.class) -@SpringBootTest(classes = Application.class) public class BPermissionTest { /** diff --git a/server/src/test/java/com/gms/domain/security/role/BRoleTest.java b/server/src/test/java/com/gms/domain/security/role/BRoleTest.java index 74d28a7..3528e13 100644 --- a/server/src/test/java/com/gms/domain/security/role/BRoleTest.java +++ b/server/src/test/java/com/gms/domain/security/role/BRoleTest.java @@ -1,6 +1,5 @@ package com.gms.domain.security.role; -import com.gms.Application; import com.gms.domain.security.permission.BPermission; import com.gms.testutil.EntityUtil; import com.gms.testutil.StringUtil; @@ -8,9 +7,6 @@ import com.gms.util.i18n.CodeI18N; import org.junit.Before; import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.test.context.junit4.SpringRunner; import org.springframework.test.util.ReflectionTestUtils; import javax.validation.ConstraintViolation; @@ -28,8 +24,6 @@ * @author Asiel Leal Celdeiro | lealceldeiro@gmail.com * @version 0.1 */ -@RunWith(SpringRunner.class) -@SpringBootTest(classes = Application.class) public class BRoleTest { /** diff --git a/server/src/test/java/com/gms/domain/security/user/EUserTest.java b/server/src/test/java/com/gms/domain/security/user/EUserTest.java index fbe5cf8..9bdedc7 100644 --- a/server/src/test/java/com/gms/domain/security/user/EUserTest.java +++ b/server/src/test/java/com/gms/domain/security/user/EUserTest.java @@ -1,17 +1,13 @@ package com.gms.domain.security.user; -import com.gms.Application; import com.gms.testutil.EntityUtil; import com.gms.testutil.StringUtil; import com.gms.testutil.validation.PersistenceValidation; import com.gms.util.i18n.CodeI18N; import org.junit.Before; import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.boot.test.context.SpringBootTest; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.authority.SimpleGrantedAuthority; -import org.springframework.test.context.junit4.SpringRunner; import org.springframework.test.util.ReflectionTestUtils; import javax.validation.ConstraintViolation; @@ -28,8 +24,6 @@ * @author Asiel Leal Celdeiro | lealceldeiro@gmail.com * @version 0.1 */ -@RunWith(SpringRunner.class) -@SpringBootTest(classes = Application.class) public class EUserTest { /** diff --git a/server/src/test/java/com/gms/testutil/EntityUtil.java b/server/src/test/java/com/gms/testutil/EntityUtil.java index 87d4bb3..4b9bb49 100644 --- a/server/src/test/java/com/gms/testutil/EntityUtil.java +++ b/server/src/test/java/com/gms/testutil/EntityUtil.java @@ -5,7 +5,7 @@ import com.gms.domain.security.role.BRole; import com.gms.domain.security.user.EUser; import com.gms.util.GMSRandom; -import org.springframework.hateoas.Resource; +import org.springframework.hateoas.EntityModel; import static com.gms.testutil.StringUtil.EXAMPLE_DESCRIPTION; import static com.gms.testutil.StringUtil.EXAMPLE_EMAIL; @@ -51,24 +51,24 @@ public static EUser getSampleUser(final String random) { } /** - * Creates a sample {@link Resource} with a {@link EUser} as content. The {@link EUser} is generated with random + * Creates a sample {@link EntityModel} with a {@link EUser} as content. The {@link EUser} is generated with random * values in its attributes. * - * @return A {@link Resource} + * @return A {@link EntityModel} */ - public static Resource getSampleUserResource() { + public static EntityModel getSampleUserResource() { return getSampleUserResource(new GMSRandom().nextString()); } /** - * Creates a sample {@link Resource} with a {@link EUser} as content. The {@link EUser} is generated with random + * Creates a sample {@link EntityModel} with a {@link EUser} as content. The {@link EUser} is generated with random * values in its attributes. * * @param random Random generator for getting the random values to be used. - * @return A {@link Resource} + * @return A {@link EntityModel} */ - public static Resource getSampleUserResource(final String random) { - return new Resource<>(getSampleUser(random)); + public static EntityModel getSampleUserResource(final String random) { + return new EntityModel<>(getSampleUser(random)); } /** @@ -91,24 +91,24 @@ public static EOwnedEntity getSampleEntity(final String random) { } /** - * Creates a sample {@link Resource} with a {@link EOwnedEntity} as content. The {@link EOwnedEntity} is generated - * with random values in its attributes. + * Creates a sample {@link EntityModel} with a {@link EOwnedEntity} as content. The {@link EOwnedEntity} is + * generated with random values in its attributes. * - * @return A {@link Resource} + * @return A {@link EntityModel} */ - public static Resource getSampleEntityResource() { + public static EntityModel getSampleEntityResource() { return getSampleEntityResource(new GMSRandom().nextString()); } /** - * Creates a sample {@link Resource} with a {@link EOwnedEntity} as content. The {@link EOwnedEntity} is generated - * with random values in its attributes. + * Creates a sample {@link EntityModel} with a {@link EOwnedEntity} as content. The {@link EOwnedEntity} is + * generated with random values in its attributes. * * @param random Random generator for getting the random values to be used. - * @return A {@link Resource} + * @return A {@link EntityModel} */ - public static Resource getSampleEntityResource(final String random) { - return new Resource<>(getSampleEntity(random)); + public static EntityModel getSampleEntityResource(final String random) { + return new EntityModel<>(getSampleEntity(random)); } /** @@ -136,24 +136,24 @@ public static BRole getSampleRole(final String random) { } /** - * Creates a sample {@link Resource} with a {@link BRole} as content. The {@link BRole} is generated with random + * Creates a sample {@link EntityModel} with a {@link BRole} as content. The {@link BRole} is generated with random * values in its attributes and its enabled attribute set to {@code true}. * - * @return A {@link Resource} + * @return A {@link EntityModel} */ - public static Resource getSampleRoleResource() { + public static EntityModel getSampleRoleResource() { return getSampleRoleResource(new GMSRandom().nextString()); } /** - * Creates a sample {@link Resource} with a {@link BRole} as content. The {@link BRole} is generated with random + * Creates a sample {@link EntityModel} with a {@link BRole} as content. The {@link BRole} is generated with random * values in its attributes and its enabled attribute set to {@code true}. * * @param random Random generator for getting the random values to be used. - * @return A {@link Resource} + * @return A {@link EntityModel} */ - public static Resource getSampleRoleResource(final String random) { - return new Resource<>(getSampleRole(random)); + public static EntityModel getSampleRoleResource(final String random) { + return new EntityModel<>(getSampleRole(random)); } /** @@ -176,24 +176,24 @@ public static BPermission getSamplePermission(final String random) { } /** - * Creates a sample {@link Resource} with a {@link BPermission} as content. The {@link BPermission} is generated + * Creates a sample {@link EntityModel} with a {@link BPermission} as content. The {@link BPermission} is generated * with random values in its attributes. * - * @return A {@link Resource} + * @return A {@link EntityModel} */ - public static Resource getSamplePermissionResource() { + public static EntityModel getSamplePermissionResource() { return getSamplePermissionResource(new GMSRandom().nextString()); } /** - * Creates a sample {@link Resource} with a {@link BPermission} as content. The {@link BPermission} is generated + * Creates a sample {@link EntityModel} with a {@link BPermission} as content. The {@link BPermission} is generated * with random values in its attributes. * * @param random Random generator for getting the random values to be used. - * @return A {@link Resource} + * @return A {@link EntityModel} */ - public static Resource getSamplePermissionResource(final String random) { - return new Resource<>(getSamplePermission(random)); + public static EntityModel getSamplePermissionResource(final String random) { + return new EntityModel<>(getSamplePermission(random)); } } diff --git a/server/src/test/java/com/gms/util/constant/DefaultConstTest.java b/server/src/test/java/com/gms/util/constant/DefaultConstTest.java index 5e4fa4f..8cab26e 100644 --- a/server/src/test/java/com/gms/util/constant/DefaultConstTest.java +++ b/server/src/test/java/com/gms/util/constant/DefaultConstTest.java @@ -1,6 +1,5 @@ package com.gms.util.constant; -import com.gms.Application; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; @@ -16,10 +15,10 @@ /** * @author Asiel Leal Celdeiro | lealceldeiro@gmail.com - * @version 0.1 + * @version 0.2 */ @RunWith(SpringRunner.class) -@SpringBootTest(classes = Application.class) +@SpringBootTest(classes = DefaultConst.class) public class DefaultConstTest { /** diff --git a/server/src/test/java/com/gms/util/constant/LinkPathTest.java b/server/src/test/java/com/gms/util/constant/LinkPathTest.java index 408077f..9a98345 100644 --- a/server/src/test/java/com/gms/util/constant/LinkPathTest.java +++ b/server/src/test/java/com/gms/util/constant/LinkPathTest.java @@ -1,19 +1,13 @@ package com.gms.util.constant; -import com.gms.Application; import org.junit.Assert; import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.test.context.junit4.SpringRunner; import org.springframework.test.util.ReflectionTestUtils; /** * @author Asiel Leal Celdeiro | lealceldeiro@gmail.com - * @version 0.1 + * @version 0.2 */ -@RunWith(SpringRunner.class) -@SpringBootTest(classes = Application.class) public class LinkPathTest { /** diff --git a/server/src/test/java/com/gms/util/constant/ResourcePathTest.java b/server/src/test/java/com/gms/util/constant/ResourcePathTest.java index 4c31932..6f0277e 100644 --- a/server/src/test/java/com/gms/util/constant/ResourcePathTest.java +++ b/server/src/test/java/com/gms/util/constant/ResourcePathTest.java @@ -1,20 +1,14 @@ package com.gms.util.constant; -import com.gms.Application; import com.gms.testutil.StaticUtil; import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.test.context.junit4.SpringRunner; import static org.junit.Assert.assertNotNull; /** * @author Asiel Leal Celdeiro | lealceldeiro@gmail.com - * @version 0.1 + * @version 0.2 */ -@RunWith(SpringRunner.class) -@SpringBootTest(classes = Application.class) public class ResourcePathTest { /** diff --git a/server/src/test/java/com/gms/util/constant/SQLExceptionCodeTest.java b/server/src/test/java/com/gms/util/constant/SQLExceptionCodeTest.java index 7b1b7b4..2bdea7e 100644 --- a/server/src/test/java/com/gms/util/constant/SQLExceptionCodeTest.java +++ b/server/src/test/java/com/gms/util/constant/SQLExceptionCodeTest.java @@ -1,20 +1,14 @@ package com.gms.util.constant; -import com.gms.Application; import com.gms.testutil.StaticUtil; import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.test.context.junit4.SpringRunner; import static org.junit.Assert.assertNotNull; /** * @author Asiel Leal Celdeiro | lealceldeiro@gmail.com - * @version 0.1 + * @version 0.2 */ -@RunWith(SpringRunner.class) -@SpringBootTest(classes = Application.class) public class SQLExceptionCodeTest { /** diff --git a/server/src/test/java/com/gms/util/constant/SecurityConstTest.java b/server/src/test/java/com/gms/util/constant/SecurityConstTest.java index 57d24cd..0d7331f 100644 --- a/server/src/test/java/com/gms/util/constant/SecurityConstTest.java +++ b/server/src/test/java/com/gms/util/constant/SecurityConstTest.java @@ -1,6 +1,5 @@ package com.gms.util.constant; -import com.gms.Application; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; @@ -14,10 +13,10 @@ /** * @author Asiel Leal Celdeiro | lealceldeiro@gmail.com - * @version 0.1 + * @version 0.2 */ @RunWith(SpringRunner.class) -@SpringBootTest(classes = Application.class) +@SpringBootTest(classes = SecurityConst.class) public class SecurityConstTest { /** diff --git a/server/src/test/java/com/gms/util/exception/GmsErrorTest.java b/server/src/test/java/com/gms/util/exception/GmsErrorTest.java index c4e307d..79af1ff 100644 --- a/server/src/test/java/com/gms/util/exception/GmsErrorTest.java +++ b/server/src/test/java/com/gms/util/exception/GmsErrorTest.java @@ -1,10 +1,6 @@ package com.gms.util.exception; -import com.gms.Application; import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.test.context.junit4.SpringRunner; import org.springframework.test.util.ReflectionTestUtils; import java.util.HashMap; @@ -20,10 +16,8 @@ /** * @author Asiel Leal Celdeiro | lealceldeiro@gmail.com - * @version 0.1 + * @version 0.2 */ -@RunWith(SpringRunner.class) -@SpringBootTest(classes = Application.class) public class GmsErrorTest { /** diff --git a/server/src/test/java/com/gms/util/exception/GmsSecurityExceptionTest.java b/server/src/test/java/com/gms/util/exception/GmsSecurityExceptionTest.java index ad6512a..3c5374e 100644 --- a/server/src/test/java/com/gms/util/exception/GmsSecurityExceptionTest.java +++ b/server/src/test/java/com/gms/util/exception/GmsSecurityExceptionTest.java @@ -1,11 +1,7 @@ package com.gms.util.exception; -import com.gms.Application; import org.junit.Before; import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.test.context.junit4.SpringRunner; import org.springframework.test.util.ReflectionTestUtils; import static org.junit.Assert.assertEquals; @@ -13,10 +9,8 @@ /** * @author Asiel Leal Celdeiro | lealceldeiro@gmail.com - * @version 0.1 + * @version 0.2 */ -@RunWith(SpringRunner.class) -@SpringBootTest(classes = Application.class) public class GmsSecurityExceptionTest { /** diff --git a/server/src/test/java/com/gms/util/exception/domain/NotFoundEntityExceptionTest.java b/server/src/test/java/com/gms/util/exception/domain/NotFoundEntityExceptionTest.java index 45d8103..90888b0 100644 --- a/server/src/test/java/com/gms/util/exception/domain/NotFoundEntityExceptionTest.java +++ b/server/src/test/java/com/gms/util/exception/domain/NotFoundEntityExceptionTest.java @@ -1,18 +1,12 @@ package com.gms.util.exception.domain; -import com.gms.Application; import org.junit.Assert; import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.test.context.junit4.SpringRunner; /** * @author Asiel Leal Celdeiro | lealceldeiro@gmail.com - * @version 0.1 + * @version 0.2 */ -@RunWith(SpringRunner.class) -@SpringBootTest(classes = Application.class) public class NotFoundEntityExceptionTest { /** diff --git a/server/src/test/java/com/gms/util/i18n/CodeI18NTest.java b/server/src/test/java/com/gms/util/i18n/CodeI18NTest.java index cd8917b..68686e9 100644 --- a/server/src/test/java/com/gms/util/i18n/CodeI18NTest.java +++ b/server/src/test/java/com/gms/util/i18n/CodeI18NTest.java @@ -1,19 +1,13 @@ package com.gms.util.i18n; -import com.gms.Application; import com.gms.testutil.StaticUtil; import org.junit.Assert; import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.test.context.junit4.SpringRunner; /** * @author Asiel Leal Celdeiro | lealceldeiro@gmail.com - * @version 0.1 + * @version 0.2 */ -@RunWith(SpringRunner.class) -@SpringBootTest(classes = Application.class) public class CodeI18NTest { /** diff --git a/server/src/test/java/com/gms/util/response/GmsResponseTest.java b/server/src/test/java/com/gms/util/response/GmsResponseTest.java index e23f8b8..04519bd 100644 --- a/server/src/test/java/com/gms/util/response/GmsResponseTest.java +++ b/server/src/test/java/com/gms/util/response/GmsResponseTest.java @@ -1,10 +1,6 @@ package com.gms.util.response; -import com.gms.Application; import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.test.context.junit4.SpringRunner; import org.springframework.test.util.ReflectionTestUtils; import static org.junit.Assert.assertArrayEquals; @@ -14,10 +10,8 @@ /** * @author Asiel Leal Celdeiro | lealceldeiro@gmail.com - * @version 0.1 + * @version 0.2 */ -@RunWith(SpringRunner.class) -@SpringBootTest(classes = Application.class) public class GmsResponseTest { /** diff --git a/server/src/test/java/com/gms/util/response/ResponseDataTest.java b/server/src/test/java/com/gms/util/response/ResponseDataTest.java index 8d3c805..74704e5 100644 --- a/server/src/test/java/com/gms/util/response/ResponseDataTest.java +++ b/server/src/test/java/com/gms/util/response/ResponseDataTest.java @@ -1,10 +1,6 @@ package com.gms.util.response; -import com.gms.Application; import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.test.context.junit4.SpringRunner; import org.springframework.test.util.ReflectionTestUtils; import static org.junit.Assert.assertEquals; @@ -12,10 +8,8 @@ /** * @author Asiel Leal Celdeiro | lealceldeiro@gmail.com - * @version 0.1 + * @version 0.2 */ -@RunWith(SpringRunner.class) -@SpringBootTest(classes = Application.class) public class ResponseDataTest { /** diff --git a/server/src/test/java/com/gms/component/security/token/JWTServiceTest.java b/server/src/test/java/com/gms/util/security/token/JWTServiceTest.java similarity index 85% rename from server/src/test/java/com/gms/component/security/token/JWTServiceTest.java rename to server/src/test/java/com/gms/util/security/token/JWTServiceTest.java index 31a66b2..3b06d60 100644 --- a/server/src/test/java/com/gms/component/security/token/JWTServiceTest.java +++ b/server/src/test/java/com/gms/util/security/token/JWTServiceTest.java @@ -1,4 +1,4 @@ -package com.gms.component.security.token; +package com.gms.util.security.token; import com.gms.Application; import com.gms.util.constant.SecurityConst; @@ -44,7 +44,7 @@ public class JWTServiceTest { */ @Before public void setUp() { - jwtService = new JWTService(sc); + jwtService = new JWTServiceImpl(sc); } /** @@ -154,13 +154,13 @@ public void expTimeOfRefreshTokenGreaterThanExpAccessToken() { Map tokenClaims = jwtService.getClaimsExtended(accessToken); Map rTokenClaims = jwtService.getClaimsExtended(refreshToken); - assertTrue(message, tokenClaims.get(JWTService.EXPIRATION) instanceof Date); - assertTrue(message, rTokenClaims.get(JWTService.EXPIRATION) instanceof Date); + assertTrue(message, tokenClaims.get(jwtService.expirationKey()) instanceof Date); + assertTrue(message, rTokenClaims.get(jwtService.expirationKey()) instanceof Date); - if (tokenClaims.get(JWTService.EXPIRATION) instanceof Date - && rTokenClaims.get(JWTService.EXPIRATION) instanceof Date) { - long rTokenTime = ((Date) rTokenClaims.get(JWTService.EXPIRATION)).getTime(); - long tokenTime = ((Date) tokenClaims.get(JWTService.EXPIRATION)).getTime(); + if (tokenClaims.get(jwtService.expirationKey()) instanceof Date + && rTokenClaims.get(jwtService.expirationKey()) instanceof Date) { + long rTokenTime = ((Date) rTokenClaims.get(jwtService.expirationKey())).getTime(); + long tokenTime = ((Date) tokenClaims.get(jwtService.expirationKey())).getTime(); assertTrue("Expiration time for refresh token must be greater than expiration time for access " + "token when default values are used", rTokenTime > tokenTime); @@ -176,7 +176,8 @@ public void getClaims() { final String auth = "ROLE_1;ROLE_2"; final String token = jwtService.createToken(sub, auth); final Map claims = - jwtService.getClaims(token, JWTService.SUBJECT, sc.getAuthoritiesHolder(), JWTService.EXPIRATION); + jwtService.getClaims(token, jwtService.subjectKey(), sc.getAuthoritiesHolder(), + jwtService.expirationKey()); assertClaimsState(claims, sub, auth); } @@ -196,13 +197,13 @@ public void getClaimsExtended() { assertClaimsState(claims, sub, auth); assertNull("Claims contains an incorrect pair key-value", claims.get(randomKey)); - assertNotNull("Expiration time is null", claims.get(JWTService.EXPIRATION)); + assertNotNull("Expiration time is null", claims.get(jwtService.expirationKey())); assertTrue("Expiration time is not an instance of Date", - claims.get(JWTService.EXPIRATION) instanceof Date); + claims.get(jwtService.expirationKey()) instanceof Date); - if (claims.get(JWTService.EXPIRATION) != null && claims.get(JWTService.EXPIRATION) instanceof Date) { + if (claims.get(jwtService.expirationKey()) != null && claims.get(jwtService.expirationKey()) instanceof Date) { assertTrue("Expiration time is not greater than the creation time of the token", - ((Date) claims.get(JWTService.EXPIRATION)).getTime() > expiresIn); + ((Date) claims.get(jwtService.expirationKey())).getTime() > expiresIn); } } @@ -210,12 +211,12 @@ private void assertClaimsState(final Map claims, final String su assertFalse("Claims map is empty", claims.isEmpty()); assertNotNull("Claims map is null", claims); - assertNotNull("Expiration time claims is null", claims.get(JWTService.EXPIRATION)); - assertNotNull("Subject claims is null", claims.get(JWTService.SUBJECT)); + assertNotNull("Expiration time claims is null", claims.get(jwtService.expirationKey())); + assertNotNull("Subject claims is null", claims.get(jwtService.subjectKey())); assertNotNull("Authorities claims is null", claims.get(sc.getAuthoritiesHolder())); - if (claims.get(JWTService.SUBJECT) != null) { - assertEquals("Subjects are not equals", subject, claims.get(JWTService.SUBJECT).toString()); + if (claims.get(jwtService.subjectKey()) != null) { + assertEquals("Subjects are not equals", subject, claims.get(jwtService.subjectKey()).toString()); } if (claims.get(sc.getAuthoritiesHolder()) != null) { assertEquals( diff --git a/server/src/test/java/com/gms/component/security/token/package-info.java b/server/src/test/java/com/gms/util/security/token/package-info.java similarity index 77% rename from server/src/test/java/com/gms/component/security/token/package-info.java rename to server/src/test/java/com/gms/util/security/token/package-info.java index c061aec..1db241d 100644 --- a/server/src/test/java/com/gms/component/security/token/package-info.java +++ b/server/src/test/java/com/gms/util/security/token/package-info.java @@ -4,4 +4,4 @@ * @author Asiel Leal Celdeiro | lealceldeiro@gmail.com * @version 0.1 */ -package com.gms.component.security.token; +package com.gms.util.security.token;