diff --git a/.gitignore b/.gitignore index 6ff2c46dc3022174a784ff45fefe20e94739a120..963909509978a7dd4f2f77017466f2849c031da6 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,7 @@ build/ !gradle/wrapper/gradle-wrapper.jar !**/src/main/**/build/ !**/src/test/**/build/ +src/main/resources/apikey.properties ### STS ### .apt_generated @@ -45,7 +46,8 @@ dev.db .LSOverride # Icon must end with two \r -Icon +Icon + # Thumbnails ._* diff --git a/src/main/java/fr/unistra/sil/erp/back/Config.java b/src/main/java/fr/unistra/sil/erp/back/Config.java deleted file mode 100644 index ed8cc4d04ba091dec77b3f0b818d535de39bef61..0000000000000000000000000000000000000000 --- a/src/main/java/fr/unistra/sil/erp/back/Config.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * CONTRAT DE LICENCE DE LOGICIEL LIBRE CeCILL-B - * https://cecill.info/licences/Licence_CeCILL-B_V1-fr.html - */ -package fr.unistra.sil.erp.back; - -/** - * Main configuration file for the application. - * @author BEAUVAIS ANTOINE - */ -public class Config { - - /** - * API version. - */ - public static final String API_VERSION = "v1"; - - /** - * Prefix for API calls. - */ - public static final String URL_PREFIX = "/api/" + API_VERSION; - - /** - * API Mapping for retrieving all items. - */ - public static final String MAPPING_RETRIEVEALL = URL_PREFIX + - "/retrieveAll"; - - /** - * API Mapping for retrieving all categories. - */ - public static final String MAPPING_GETCATEGORIES = URL_PREFIX + - "/retrieveCategories"; - - /** - * API Mapping for submitting transactions. - */ - public static final String MAPPING_SUBTRANSAC = URL_PREFIX + - "/submitTransaction"; - - /** - * API Mapping for retrieving stocks. - */ - public static final String MAPPING_GETSTOCKS = URL_PREFIX + - "/retrieveStocks"; -} diff --git a/src/main/java/fr/unistra/sil/erp/back/WebMvcConfig.java b/src/main/java/fr/unistra/sil/erp/back/WebMvcConfig.java new file mode 100644 index 0000000000000000000000000000000000000000..9a5b3b329107b2a9b200815ec7a016765851c7b9 --- /dev/null +++ b/src/main/java/fr/unistra/sil/erp/back/WebMvcConfig.java @@ -0,0 +1,88 @@ +/* + * CONTRAT DE LICENCE DE LOGICIEL LIBRE CeCILL-B + * https://cecill.info/licences/Licence_CeCILL-B_V1-fr.html + */ +package fr.unistra.sil.erp.back; + +import fr.unistra.sil.erp.back.interceptor.api.ApiAuthenticationInterceptor; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.PropertySource; +import org.springframework.context.annotation.PropertySources; +import org.springframework.core.env.Environment; +import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer; +import org.springframework.web.servlet.config.annotation.EnableWebMvc; +import org.springframework.web.servlet.config.annotation.InterceptorRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +/** + * Main configuration file for the application. + * @author BEAUVAIS ANTOINE + */ +@Configuration +@EnableWebMvc +@PropertySources( + @PropertySource("/apikey.properties") +) +public class WebMvcConfig implements WebMvcConfigurer { + + @Autowired + private Environment env; + + /** + * API version. + */ + public static final String API_VERSION = "v1"; + + /** + * API prefix. + */ + public static final String API_PREFIX = "/api/"; + + /** + * Prefix for API calls. + */ + public static final String API_FULL_PREFIX = API_PREFIX + API_VERSION; + + /** + * API Mapping for retrieving all items. + */ + public static final String MAPPING_RETRIEVEALL = API_FULL_PREFIX + + "/retrieveAll"; + + /** + * API Mapping for retrieving all categories. + */ + public static final String MAPPING_GETCATEGORIES = API_FULL_PREFIX + + "/retrieveCategories"; + + /** + * API Mapping for submitting transactions. + */ + public static final String MAPPING_SUBTRANSAC = API_FULL_PREFIX + + "/submitTransaction"; + + /** + * API Mapping for retrieving stocks. + */ + public static final String MAPPING_GETSTOCKS = API_FULL_PREFIX + + "/retrieveStocks"; + + + /* + // TODO: Define default servlet. + @Override + public void configureDefaultServletHandling( + DefaultServletHandlerConfigurer configurer) { + configurer.enable(); + }*/ + + @Override + public void addInterceptors(InterceptorRegistry registry) { + + registry.addInterceptor(new ApiAuthenticationInterceptor( + this.env.getProperty("api.key"))) + .addPathPatterns(API_PREFIX + "**"); + + } +} diff --git a/src/main/java/fr/unistra/sil/erp/back/controller/api/ApiRetrieveCategoriesController.java b/src/main/java/fr/unistra/sil/erp/back/controller/api/ApiRetrieveCategoriesController.java index fa4a767df3d1d302acd0bec3952e3620f000e2b8..03f98dd9dd7ae32ef39c41291abde005b058bdc4 100644 --- a/src/main/java/fr/unistra/sil/erp/back/controller/api/ApiRetrieveCategoriesController.java +++ b/src/main/java/fr/unistra/sil/erp/back/controller/api/ApiRetrieveCategoriesController.java @@ -4,7 +4,7 @@ */ package fr.unistra.sil.erp.back.controller.api; -import static fr.unistra.sil.erp.back.Config.MAPPING_GETCATEGORIES; +import static fr.unistra.sil.erp.back.WebMvcConfig.MAPPING_GETCATEGORIES; import fr.unistra.sil.erp.back.DatabaseSystem; import fr.unistra.sil.erp.back.controller.IRetrieveCategoriesController; import fr.unistra.sil.erp.back.model.Category; diff --git a/src/main/java/fr/unistra/sil/erp/back/controller/api/ApiRetrieveInfoController.java b/src/main/java/fr/unistra/sil/erp/back/controller/api/ApiRetrieveInfoController.java index ba8c6afd0d04eab84780a06057e61b2683d81868..1c8801d284d2bf5ca1dc5e43ee2613a49b64df0f 100644 --- a/src/main/java/fr/unistra/sil/erp/back/controller/api/ApiRetrieveInfoController.java +++ b/src/main/java/fr/unistra/sil/erp/back/controller/api/ApiRetrieveInfoController.java @@ -4,7 +4,7 @@ */ package fr.unistra.sil.erp.back.controller.api; -import static fr.unistra.sil.erp.back.Config.MAPPING_RETRIEVEALL; +import static fr.unistra.sil.erp.back.WebMvcConfig.MAPPING_RETRIEVEALL; import fr.unistra.sil.erp.back.DatabaseSystem; import fr.unistra.sil.erp.back.controller.IRetrieveInfoController; import fr.unistra.sil.erp.back.model.Item; diff --git a/src/main/java/fr/unistra/sil/erp/back/controller/api/ApiRetrieveStocks.java b/src/main/java/fr/unistra/sil/erp/back/controller/api/ApiRetrieveStocks.java index 0e47d0062cc4dcfdceff438037734fb2815f6fe8..251034e54e8016f5c3bb777af38af37552d24a1d 100644 --- a/src/main/java/fr/unistra/sil/erp/back/controller/api/ApiRetrieveStocks.java +++ b/src/main/java/fr/unistra/sil/erp/back/controller/api/ApiRetrieveStocks.java @@ -4,7 +4,7 @@ */ package fr.unistra.sil.erp.back.controller.api; -import static fr.unistra.sil.erp.back.Config.MAPPING_GETSTOCKS; +import static fr.unistra.sil.erp.back.WebMvcConfig.MAPPING_GETSTOCKS; import fr.unistra.sil.erp.back.DatabaseSystem; import fr.unistra.sil.erp.back.controller.IRetrieveStocks; import fr.unistra.sil.erp.back.db.DatabaseConnectionException; diff --git a/src/main/java/fr/unistra/sil/erp/back/controller/api/ApiSubmitTransactionController.java b/src/main/java/fr/unistra/sil/erp/back/controller/api/ApiSubmitTransactionController.java index b39c3031d09cf32350521eb95e9bf2188969e7a1..8396f29fc2641782a64726ebd65503326b9039dd 100644 --- a/src/main/java/fr/unistra/sil/erp/back/controller/api/ApiSubmitTransactionController.java +++ b/src/main/java/fr/unistra/sil/erp/back/controller/api/ApiSubmitTransactionController.java @@ -6,7 +6,7 @@ package fr.unistra.sil.erp.back.controller.api; import com.google.gson.Gson; import com.google.gson.JsonParseException; -import static fr.unistra.sil.erp.back.Config.MAPPING_SUBTRANSAC; +import static fr.unistra.sil.erp.back.WebMvcConfig.MAPPING_SUBTRANSAC; import fr.unistra.sil.erp.back.DatabaseSystem; import fr.unistra.sil.erp.back.controller.ISubmitTransactionController; import fr.unistra.sil.erp.back.db.DatabaseConnectionException; diff --git a/src/main/java/fr/unistra/sil/erp/back/interceptor/api/ApiAuthenticationInterceptor.java b/src/main/java/fr/unistra/sil/erp/back/interceptor/api/ApiAuthenticationInterceptor.java new file mode 100644 index 0000000000000000000000000000000000000000..c6057937c3351e1431413b2dfa2aa591af9df781 --- /dev/null +++ b/src/main/java/fr/unistra/sil/erp/back/interceptor/api/ApiAuthenticationInterceptor.java @@ -0,0 +1,101 @@ +/* + * CONTRAT DE LICENCE DE LOGICIEL LIBRE CeCILL-B + * https://cecill.info/licences/Licence_CeCILL-B_V1-fr.html + */ +package fr.unistra.sil.erp.back.interceptor.api; + +import com.google.gson.Gson; +import fr.unistra.sil.erp.back.model.ErrorMessage; +import java.io.IOException; +import java.io.PrintWriter; +import java.util.logging.Level; +import java.util.logging.Logger; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import org.springframework.web.servlet.HandlerInterceptor; + +/** + * API Authentication Interceptor. + * + * Each request going through an API call will be processed + * by this interceptor first. + * @author BEAUVAIS ANTOINE + */ +public class ApiAuthenticationInterceptor implements HandlerInterceptor { + + /** + * API key. + */ + private final String apikey; + + public ApiAuthenticationInterceptor(String apikey) + { + this.apikey = apikey; + } + + @Override + public boolean preHandle(HttpServletRequest request, + HttpServletResponse response, Object handler) + { + if(this.apikey == null) + { + response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); + Gson gson = new Gson(); + ErrorMessage errMsg = new ErrorMessage("Missing API key on server"); + String responseBody = gson.toJson(errMsg); + + response.setContentType("application/json"); + response.setCharacterEncoding("UTF-8"); + try { + PrintWriter printBody = response.getWriter(); + printBody.print(responseBody); + } catch (IOException ex) { + Logger.getLogger(ApiAuthenticationInterceptor.class.getName()) + .log(Level.SEVERE, "Failed to write body.", ex); + } + return false; + } + + String login = request.getHeader("apikey"); + if(login == null) + { + response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); + Gson gson = new Gson(); + ErrorMessage errMsg = new ErrorMessage("Missing API key."); + String responseBody = gson.toJson(errMsg); + + response.setContentType("application/json"); + response.setCharacterEncoding("UTF-8"); + try { + PrintWriter printBody = response.getWriter(); + printBody.print(responseBody); + } catch (IOException ex) { + Logger.getLogger(ApiAuthenticationInterceptor.class.getName()) + .log(Level.SEVERE, "Failed to write body.", ex); + } + return false; + } + + if(! login.equals(this.apikey) ) + { + response.setStatus(HttpServletResponse.SC_FORBIDDEN); + Gson gson = new Gson(); + ErrorMessage errMsg = new ErrorMessage("Invalid API key."); + String responseBody = gson.toJson(errMsg); + + response.setContentType("application/json"); + response.setCharacterEncoding("UTF-8"); + try { + PrintWriter printBody = response.getWriter(); + printBody.print(responseBody); + } catch (IOException ex) { + Logger.getLogger(ApiAuthenticationInterceptor.class.getName()) + .log(Level.SEVERE, "Failed to write body.", ex); + } + return false; + } + + return true; + } + +}