From 67fd9986adf053d9b9080c1e47c5f774574420d6 Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Tue, 17 Jul 2018 20:43:32 +0530 Subject: [PATCH 001/116] Updated README.md and Postman collection --- README.md | 5 - .../Spring Lemon 1.0.postman_collection.json | 95 +++++++------------ 2 files changed, 36 insertions(+), 64 deletions(-) diff --git a/README.md b/README.md index 51d73cd1..13cc3648 100644 --- a/README.md +++ b/README.md @@ -41,11 +41,6 @@ Watch [this video tutorial](https://www.naturalprogrammer.com/p/spring-lemon-res 1. [Submit an issue](https://github.com/naturalprogrammer/spring-lemon/issues) for any bug or enhancement. Please check first that the issue isn't already reported earlier. 1. Mentoring, training and professional help is provided by [naturalprogrammer.com](http://www.naturalprogrammer.com/consulting/). -## Donate -Like Spring Lemon? We have been putting continuous efforts to develop and maintain it. If it's being useful to you, why not donate a little amount — it’ll help us give more time to the project! - -[Click here](http://www.naturalprogrammer.com/support-spring-lemon/) to donate. - ## Releases 1. See [here](https://github.com/naturalprogrammer/spring-lemon/releases). diff --git a/lemon-demo-jpa/src/test/resources/postman/Spring Lemon 1.0.postman_collection.json b/lemon-demo-jpa/src/test/resources/postman/Spring Lemon 1.0.postman_collection.json index 1b6ef2e9..ec088f47 100644 --- a/lemon-demo-jpa/src/test/resources/postman/Spring Lemon 1.0.postman_collection.json +++ b/lemon-demo-jpa/src/test/resources/postman/Spring Lemon 1.0.postman_collection.json @@ -46,7 +46,7 @@ }, "response": [ { - "id": "dc13c098-4ab6-4708-9a22-4c6647aa1698", + "id": "94e97d70-c5b8-46d1-9a0a-fdd64c888f71", "name": "Ping", "originalRequest": { "method": "GET", @@ -205,11 +205,13 @@ ] }, "url": { - "raw": "{{lemonDemoUrl}}/login", + "raw": "{{lemonDemoUrl}}/api/core/login", "host": [ "{{lemonDemoUrl}}" ], "path": [ + "api", + "core", "login" ] }, @@ -217,7 +219,7 @@ }, "response": [ { - "id": "e6eefb5e-b4a3-4b42-b9ad-2d2e6dbfb48d", + "id": "fd19ca94-a61e-4af6-8831-97d2ed9a07b7", "name": "Login", "originalRequest": { "method": "POST", @@ -252,11 +254,13 @@ ] }, "url": { - "raw": "{{lemonDemoUrl}}/login", + "raw": "{{lemonDemoUrl}}/api/core/login", "host": [ "{{lemonDemoUrl}}" ], "path": [ + "api", + "core", "login" ] } @@ -330,7 +334,7 @@ "body": "{\"id\":9,\"username\":\"admin@example.com\",\"roles\":[\"ADMIN\"],\"tag\":{\"name\":\"Administrator\"},\"unverified\":false,\"blocked\":false,\"admin\":true,\"goodUser\":true,\"goodAdmin\":true}" }, { - "id": "e3a0b42d-4ad2-46bd-aa6e-ef47d47c60c2", + "id": "5badab55-018e-4fd7-baf4-31c9f6541643", "name": "Login with wrong credentials", "originalRequest": { "method": "POST", @@ -365,11 +369,13 @@ ] }, "url": { - "raw": "{{lemonDemoUrl}}/login", + "raw": "{{lemonDemoUrl}}/api/core/login", "host": [ "{{lemonDemoUrl}}" ], "path": [ + "api", + "core", "login" ] } @@ -486,7 +492,7 @@ }, "response": [ { - "id": "123567f0-1a53-4fe1-b75d-3775da8559e1", + "id": "be379d95-60bb-4066-af3c-1303bc1f879f", "name": "Get context with Authorization header", "originalRequest": { "method": "GET", @@ -618,7 +624,7 @@ "body": "{\"context\":{\"reCaptchaSiteKey\":\"6LdwxRcUAAAAABkhOGWQXhl9FsR27D5YUJRuGzx0\",\"shared\":{\"fooBar\":\"123...\"}},\"user\":{\"id\":2,\"username\":\"skpatel20@gmail.com\",\"roles\":[\"UNVERIFIED\"],\"tag\":{\"name\":\"Sanjay Patel\"},\"unverified\":true,\"blocked\":false,\"admin\":false,\"goodUser\":false,\"goodAdmin\":false}}" }, { - "id": "6f023dfc-2374-4155-86b7-236b150c427e", + "id": "4b46a9e7-8fc7-4c28-aa3d-f8da31ac72af", "name": "Get context using a wrong Authorization token", "originalRequest": { "method": "GET", @@ -744,7 +750,7 @@ "body": "{\"timestamp\":\"2018-03-03T06:21:34.748+0000\",\"status\":401,\"error\":\"Unauthorized\",\"message\":\"Authentication Failed: Invalid JWT serialization: Missing dot delimiter(s)\",\"path\":\"/api/core/context\"}" }, { - "id": "761ee1eb-aaa5-48ae-ac7b-d91a666f7ae1", + "id": "90c0d043-46b7-4b23-9dca-2d12f0278ab4", "name": "Get context without Authorization header", "originalRequest": { "method": "GET", @@ -975,7 +981,7 @@ }, "response": [ { - "id": "e7d318ce-ae30-4120-a3b2-4207ffcf6661", + "id": "c76cf940-d63b-4692-8fa5-bf1eb6a808d2", "name": "Sign up with invalid data", "originalRequest": { "method": "POST", @@ -1100,7 +1106,7 @@ "body": "{\"exception\":\"ConstraintViolationException\",\"error\":\"Unprocessable Entity\",\"message\":\"Validation Error\",\"status\":422,\"errors\":[{\"field\":\"user.email\",\"code\":\"{com.naturalprogrammer.spring.invalid.email}\",\"message\":\"Not a well formed email address\"},{\"field\":\"user.password\",\"code\":\"{com.naturalprogrammer.spring.invalid.password.size}\",\"message\":\"Password must be between 6 and 50 characters\"},{\"field\":\"user.name\",\"code\":\"{blank.name}\",\"message\":\"Name required\"},{\"field\":\"user.email\",\"code\":\"{com.naturalprogrammer.spring.invalid.email.size}\",\"message\":\"Email must be between 4 and 250 characters\"}]}" }, { - "id": "ee65ea2e-743a-4135-bbab-fad97ce3c06f", + "id": "23eba689-6667-49f7-b1ef-501148a40922", "name": "Sign up", "originalRequest": { "method": "POST", @@ -1275,7 +1281,7 @@ }, "response": [ { - "id": "7b70613c-b89e-45e4-b641-4ccfbde839d8", + "id": "bf12db2b-2585-4ca2-a709-65604a2398d8", "name": "Resend verification mail", "originalRequest": { "method": "POST", @@ -1434,7 +1440,7 @@ }, "response": [ { - "id": "79277fc4-5434-4863-99b7-cf4529a4cbcf", + "id": "faaee1e5-9286-4611-889e-260834a7205b", "name": "Verify User", "originalRequest": { "method": "POST", @@ -1599,7 +1605,7 @@ }, "response": [ { - "id": "b7913835-3286-4c8f-b2c8-56f8432bf971", + "id": "dfa67f50-9db1-4801-94dd-b7bba429f4c9", "name": "Forgot password", "originalRequest": { "method": "POST", @@ -1719,25 +1725,12 @@ "header": [ { "key": "Content-Type", - "value": "application/x-www-form-urlencoded" + "value": "application/json" } ], "body": { - "mode": "urlencoded", - "urlencoded": [ - { - "key": "newPassword", - "value": "a-new-password", - "description": "", - "type": "text" - }, - { - "key": "code", - "value": "eyJlbmMiOiJBMTI4Q0JDLUhTMjU2IiwiYWxnIjoiZGlyIn0..HoDu5pdYAx8fS7p9PKCl5g.jRNA1Vu0ZydW9G4bDd6f7GirpNahXtytXke9i7M5xmrsTqUvCitotGwOm3NwhmyIUcBeRTS53lx1SCxDa8cuv9McD2v2exRfKhnNu1i7cG1E10Cmb4m9nuDuAP2LviXpUOLJyYUFRGrxQOrCwwkMNQ.iN6xYjU1Xe-w9O4VDKDEOA", - "description": "", - "type": "text" - } - ] + "mode": "raw", + "raw": "{\n\t\"newPassword\": \"a-new-password\",\n\t\"code\": \"eyJlbmMiOiJBMTI4Q0JDLUhTMjU2IiwiYWxnIjoiZGlyIn0..HoDu5pdYAx8fS7p9PKCl5g.jRNA1Vu0ZydW9G4bDd6f7GirpNahXtytXke9i7M5xmrsTqUvCitotGwOm3NwhmyIUcBeRTS53lx1SCxDa8cuv9McD2v2exRfKhnNu1i7cG1E10Cmb4m9nuDuAP2LviXpUOLJyYUFRGrxQOrCwwkMNQ.iN6xYjU1Xe-w9O4VDKDEOA\"\n}" }, "url": { "raw": "{{lemonDemoUrl}}/api/core/reset-password", @@ -1754,35 +1747,19 @@ }, "response": [ { - "id": "bbc954f4-d67a-421c-9045-58cf125ecd31", + "id": "e34d5413-6cf8-40d5-8d17-1dbf7bde7af5", "name": "Reset password", "originalRequest": { "method": "POST", "header": [ { "key": "Content-Type", - "type": "text", - "name": "Content-Type", - "value": "application/x-www-form-urlencoded", - "disabled": false + "value": "application/json" } ], "body": { - "mode": "urlencoded", - "urlencoded": [ - { - "key": "newPassword", - "value": "a-new-password", - "description": "", - "type": "text" - }, - { - "key": "code", - "value": "eyJlbmMiOiJBMTI4Q0JDLUhTMjU2IiwiYWxnIjoiZGlyIn0..HoDu5pdYAx8fS7p9PKCl5g.jRNA1Vu0ZydW9G4bDd6f7GirpNahXtytXke9i7M5xmrsTqUvCitotGwOm3NwhmyIUcBeRTS53lx1SCxDa8cuv9McD2v2exRfKhnNu1i7cG1E10Cmb4m9nuDuAP2LviXpUOLJyYUFRGrxQOrCwwkMNQ.iN6xYjU1Xe-w9O4VDKDEOA", - "description": "", - "type": "text" - } - ] + "mode": "raw", + "raw": "{\n\t\"newPassword\": \"a-new-password\",\n\t\"code\": \"eyJlbmMiOiJBMTI4Q0JDLUhTMjU2IiwiYWxnIjoiZGlyIn0..HoDu5pdYAx8fS7p9PKCl5g.jRNA1Vu0ZydW9G4bDd6f7GirpNahXtytXke9i7M5xmrsTqUvCitotGwOm3NwhmyIUcBeRTS53lx1SCxDa8cuv9McD2v2exRfKhnNu1i7cG1E10Cmb4m9nuDuAP2LviXpUOLJyYUFRGrxQOrCwwkMNQ.iN6xYjU1Xe-w9O4VDKDEOA\"\n}" }, "url": { "raw": "{{lemonDemoUrl}}/api/core/reset-password", @@ -1929,7 +1906,7 @@ }, "response": [ { - "id": "d1ccdda8-bf5d-446a-a468-e1fbc607e26c", + "id": "a5278a35-86da-4ead-b2d3-9860c1861687", "name": "Fetch user by email - Others", "originalRequest": { "method": "POST", @@ -2042,7 +2019,7 @@ "body": "{\"id\":11,\"version\":2,\"roles\":[],\"name\":\"Sample User\",\"new\":false}" }, { - "id": "5595f812-2a4f-4360-bf32-f1813a22a6f3", + "id": "c45a4fbc-9a0b-4397-8a0a-ce8d363efe99", "name": "Fetch user by email - Self or Admin", "originalRequest": { "method": "POST", @@ -2205,7 +2182,7 @@ }, "response": [ { - "id": "2448a1cc-627d-4d23-a10f-fa4f6d32efc7", + "id": "2dce2342-b2e3-4269-a343-7727addd2e67", "name": "Fetch user by ID - Self or Admin", "originalRequest": { "method": "GET", @@ -2331,7 +2308,7 @@ "body": "{\"id\":2,\"version\":2,\"email\":\"skpatel20+lemon1842637@example.com\",\"roles\":[],\"name\":\"Sample User\",\"new\":false}" }, { - "id": "7288f472-5f1e-437a-be18-bd3e0e11d789", + "id": "faf6cfba-2759-4a2d-b983-2e6a7a442260", "name": "Fetch user by ID - Others", "originalRequest": { "method": "GET", @@ -2502,7 +2479,7 @@ }, "response": [ { - "id": "9c1fc11b-c7e2-4406-9db2-07325bdd6da2", + "id": "380c4cbe-efd5-4bdc-9c2d-54af1ff78f54", "name": "Update user", "originalRequest": { "method": "PATCH", @@ -2689,7 +2666,7 @@ }, "response": [ { - "id": "81590aa2-a281-4755-bf43-568fc79f82b1", + "id": "2f63c1e3-be33-47ca-8275-7efd188c19d3", "name": "Change password", "originalRequest": { "method": "POST", @@ -2871,7 +2848,7 @@ }, "response": [ { - "id": "f7320de8-3bd4-45ac-851a-9b4db1870fe5", + "id": "290c8a5c-a3fd-4a5b-a6ae-4b76c894494c", "name": "Requesting for changing email", "originalRequest": { "method": "POST", @@ -3052,7 +3029,7 @@ }, "response": [ { - "id": "09ead591-4e70-4726-b240-f29b5e0f16af", + "id": "e26ba30b-8978-4c97-8709-1972ca5a56a7", "name": "Change email", "originalRequest": { "method": "POST", @@ -3236,7 +3213,7 @@ }, "response": [ { - "id": "af5ab736-94b8-4ef8-9f43-c240d1331df1", + "id": "8ff37fe9-e010-4add-9f79-b7298de2d943", "name": "Fetch new token", "originalRequest": { "method": "POST", From f4af2c429584c601de7583398407ff47baff78bd Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Wed, 18 Jul 2018 07:21:49 +0530 Subject: [PATCH 002/116] Removed reference to JavaDoc --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index 13cc3648..4f302c05 100644 --- a/README.md +++ b/README.md @@ -32,7 +32,6 @@ Watch [this video tutorial](https://www.naturalprogrammer.com/p/spring-lemon-res 1. [Video Tutorial](https://www.naturalprogrammer.com/p/spring-lemon-restful-web-services-development) 1. _[Example application](https://github.com/naturalprogrammer/lemon-demo)_ — A sample application using Spring Lemon. Quite similar to the one developed in the above [getting started guide](https://github.com/naturalprogrammer/spring-lemon/wiki/Getting-Started-With-Spring-Lemon), but additionally has automated tests. 1. _[API documentation](https://documenter.getpostman.com/view/305915/RVu2mqEH)_ of the above application. -1. Spring Lemon [JavaDoc](https://naturalprogrammer.github.io/javadoc/spring-lemon/1.0.0.m2/) 1. _[Example Angular 1.x front-end application](https://github.com/naturalprogrammer/lemon-demo-angular1)_ — A sample AngularJS 1.x front-end. It'll work both for the application developed in the above [getting started guide](https://documenter.getpostman.com/view/305915/lemondemo/RVnPL46k) as well as the [Lemon Demo application](https://github.com/naturalprogrammer/lemon-demo). 1. _Mastering Spring RESTful Web Services Development_ — Ultimate course to master REST API development using Spring. Also covers Spring Lemon in depth. A must guide if you want to become an expert Spring developer, whether you use Spring Lemon or not. [Click here](https://www.naturalprogrammer.com/p/spring-restful-web-services-tutorial-i) to get part I now for FREE! From e859b2c8c38f2057bf57b9feebad4e884b579a92 Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Wed, 18 Jul 2018 07:30:08 +0530 Subject: [PATCH 003/116] Fixed links --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 4f302c05..80354a2a 100644 --- a/README.md +++ b/README.md @@ -30,9 +30,9 @@ Watch [this video tutorial](https://www.naturalprogrammer.com/p/spring-lemon-res 1. _Getting started guide_ 1. [Book](https://github.com/naturalprogrammer/spring-lemon/wiki/Getting-Started-With-Spring-Lemon) 1. [Video Tutorial](https://www.naturalprogrammer.com/p/spring-lemon-restful-web-services-development) -1. _[Example application](https://github.com/naturalprogrammer/lemon-demo)_ — A sample application using Spring Lemon. Quite similar to the one developed in the above [getting started guide](https://github.com/naturalprogrammer/spring-lemon/wiki/Getting-Started-With-Spring-Lemon), but additionally has automated tests. +1. _[Example application](https://github.com/naturalprogrammer/spring-lemon/tree/master/lemon-demo-jpa)_ — A sample application using Spring Lemon. Quite similar to the one developed in the above [getting started guide](https://github.com/naturalprogrammer/spring-lemon/wiki/Getting-Started-With-Spring-Lemon), but additionally has automated tests. 1. _[API documentation](https://documenter.getpostman.com/view/305915/RVu2mqEH)_ of the above application. -1. _[Example Angular 1.x front-end application](https://github.com/naturalprogrammer/lemon-demo-angular1)_ — A sample AngularJS 1.x front-end. It'll work both for the application developed in the above [getting started guide](https://documenter.getpostman.com/view/305915/lemondemo/RVnPL46k) as well as the [Lemon Demo application](https://github.com/naturalprogrammer/lemon-demo). +1. _[Example AngularJS front-end application](https://github.com/naturalprogrammer/spring-lemon/tree/master/lemon-demo-angularjs)_ — A sample AngularJS 1.x front-end. It'll work both for the application developed in the above [getting started guide](https://github.com/naturalprogrammer/spring-lemon/wiki/Getting-Started-With-Spring-Lemon) as well as the [Lemon Demo application](https://github.com/naturalprogrammer/spring-lemon/tree/master/lemon-demo-jpa). See the [Getting Started Guide](https://github.com/naturalprogrammer/spring-lemon/wiki/Getting-Started-With-Spring-Lemon) on how to use it. 1. _Mastering Spring RESTful Web Services Development_ — Ultimate course to master REST API development using Spring. Also covers Spring Lemon in depth. A must guide if you want to become an expert Spring developer, whether you use Spring Lemon or not. [Click here](https://www.naturalprogrammer.com/p/spring-restful-web-services-tutorial-i) to get part I now for FREE! ## Help and Support @@ -40,6 +40,6 @@ Watch [this video tutorial](https://www.naturalprogrammer.com/p/spring-lemon-res 1. [Submit an issue](https://github.com/naturalprogrammer/spring-lemon/issues) for any bug or enhancement. Please check first that the issue isn't already reported earlier. 1. Mentoring, training and professional help is provided by [naturalprogrammer.com](http://www.naturalprogrammer.com/consulting/). -## Releases +## Releases and Breaking Changes 1. See [here](https://github.com/naturalprogrammer/spring-lemon/releases). From 6f3aa1655d110f5260585730b1aa6e1093e4f6b4 Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Wed, 18 Jul 2018 11:27:07 +0530 Subject: [PATCH 004/116] Updated README --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 80354a2a..24386e4e 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,7 @@ Watch [this video tutorial](https://www.naturalprogrammer.com/p/spring-lemon-res ## Documentation and Resources -> _Part I of our [Mastering Spring RESTful Web Services Development](https://www.naturalprogrammer.com/p/spring-restful-web-services-tutorial-i) — the ultimate course to master REST API development using Spring whether you use Spring Lemon or not — is now available for FREE._ +> _Our [Spring Framework Recipes For Real World Application Development](https://www.naturalprogrammer.com/p/spring-framework-book-of-best-practices) — a live book discussing key real-world topics on developing Spring applications and APIs, including many Spring Lemon topics — is now available for FREE._ 1. Feature demo: https://youtu.be/6mNg-Feq8CY 1. _Getting started guide_ @@ -33,12 +33,12 @@ Watch [this video tutorial](https://www.naturalprogrammer.com/p/spring-lemon-res 1. _[Example application](https://github.com/naturalprogrammer/spring-lemon/tree/master/lemon-demo-jpa)_ — A sample application using Spring Lemon. Quite similar to the one developed in the above [getting started guide](https://github.com/naturalprogrammer/spring-lemon/wiki/Getting-Started-With-Spring-Lemon), but additionally has automated tests. 1. _[API documentation](https://documenter.getpostman.com/view/305915/RVu2mqEH)_ of the above application. 1. _[Example AngularJS front-end application](https://github.com/naturalprogrammer/spring-lemon/tree/master/lemon-demo-angularjs)_ — A sample AngularJS 1.x front-end. It'll work both for the application developed in the above [getting started guide](https://github.com/naturalprogrammer/spring-lemon/wiki/Getting-Started-With-Spring-Lemon) as well as the [Lemon Demo application](https://github.com/naturalprogrammer/spring-lemon/tree/master/lemon-demo-jpa). See the [Getting Started Guide](https://github.com/naturalprogrammer/spring-lemon/wiki/Getting-Started-With-Spring-Lemon) on how to use it. -1. _Mastering Spring RESTful Web Services Development_ — Ultimate course to master REST API development using Spring. Also covers Spring Lemon in depth. A must guide if you want to become an expert Spring developer, whether you use Spring Lemon or not. [Click here](https://www.naturalprogrammer.com/p/spring-restful-web-services-tutorial-i) to get part I now for FREE! +1. _[Spring Framework Recipes For Real World Application Development](https://www.naturalprogrammer.com/p/spring-framework-book-of-best-practices)_ — a live book discussing key real-world topics on developing Spring applications and APIs. Includes key Spring Lemon topics. [Click here](https://www.naturalprogrammer.com/p/spring-framework-book-of-best-practices) to get it now for FREE! ## Help and Support 1. Community help is available at [stackoverflow.com](http://stackoverflow.com/questions/tagged/spring-lemon), under the `spring-lemon` tag. Do not miss to tag the questions with `spring-lemon`! 1. [Submit an issue](https://github.com/naturalprogrammer/spring-lemon/issues) for any bug or enhancement. Please check first that the issue isn't already reported earlier. -1. Mentoring, training and professional help is provided by [naturalprogrammer.com](http://www.naturalprogrammer.com/consulting/). +1. Mentoring, training and professional help is provided by [naturalprogrammer.com](https://www.naturalprogrammer.com). ## Releases and Breaking Changes From cec24f27efa383d72d94bdc64e7f057d5d8eee59 Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Wed, 18 Jul 2018 11:38:10 +0530 Subject: [PATCH 005/116] Updated README --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index 24386e4e..0d03ce15 100644 --- a/README.md +++ b/README.md @@ -34,6 +34,11 @@ Watch [this video tutorial](https://www.naturalprogrammer.com/p/spring-lemon-res 1. _[API documentation](https://documenter.getpostman.com/view/305915/RVu2mqEH)_ of the above application. 1. _[Example AngularJS front-end application](https://github.com/naturalprogrammer/spring-lemon/tree/master/lemon-demo-angularjs)_ — A sample AngularJS 1.x front-end. It'll work both for the application developed in the above [getting started guide](https://github.com/naturalprogrammer/spring-lemon/wiki/Getting-Started-With-Spring-Lemon) as well as the [Lemon Demo application](https://github.com/naturalprogrammer/spring-lemon/tree/master/lemon-demo-jpa). See the [Getting Started Guide](https://github.com/naturalprogrammer/spring-lemon/wiki/Getting-Started-With-Spring-Lemon) on how to use it. 1. _[Spring Framework Recipes For Real World Application Development](https://www.naturalprogrammer.com/p/spring-framework-book-of-best-practices)_ — a live book discussing key real-world topics on developing Spring applications and APIs. Includes key Spring Lemon topics. [Click here](https://www.naturalprogrammer.com/p/spring-framework-book-of-best-practices) to get it now for FREE! +1. Video tutorials coming soon: + 1. Spring Framework 5 REST API Development — A Complete Blueprint For Real-World Developers + 1. Spring WebFlux Reactive REST API Development — A Complete Blueprint For Real-World Developers + 1. Real World Microservices Using Spring Cloud — A Rapid Course + 1. Register [here](https://www.naturalprogrammer.com/p/spring-framework-book-of-best-practices) to get notified when the above courses get released ## Help and Support 1. Community help is available at [stackoverflow.com](http://stackoverflow.com/questions/tagged/spring-lemon), under the `spring-lemon` tag. Do not miss to tag the questions with `spring-lemon`! From 44545cb338735e2b57b93d647e13502ad109f79f Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Fri, 20 Jul 2018 21:19:39 +0530 Subject: [PATCH 006/116] Beginning to code reactive tests --- lemon-demo-jpa/pom.xml | 2 +- .../lemondemo/controllers/MyController.java | 4 +- lemon-demo-reactive/pom.xml | 2 +- .../lemondemo/controllers/MyController.java | 4 +- .../spring/lemondemo/domain/User.java | 18 +-- .../spring/lemondemo/AbstractTests.java | 29 +++++ .../LemonDemoReactiveApplicationTests.java | 16 --- .../spring/lemondemo/LoginTests.java | 39 +++++++ .../spring/lemondemo/MyTestUtils.java | 107 ++++++++++++++++++ .../spring/lemondemo/TestUserDto.java | 27 +++++ .../spring/lemondemo/UserClient.java | 12 ++ pom.xml | 2 +- spring-lemon-commons/pom.xml | 2 +- spring-lemon-exceptions/pom.xml | 2 +- spring-lemon-jpa/pom.xml | 2 +- spring-lemon-reactive/pom.xml | 2 +- 16 files changed, 229 insertions(+), 41 deletions(-) create mode 100644 lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/AbstractTests.java delete mode 100644 lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/LemonDemoReactiveApplicationTests.java create mode 100644 lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/LoginTests.java create mode 100644 lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/MyTestUtils.java create mode 100644 lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/TestUserDto.java create mode 100644 lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/UserClient.java diff --git a/lemon-demo-jpa/pom.xml b/lemon-demo-jpa/pom.xml index f49a7e52..58ba6953 100644 --- a/lemon-demo-jpa/pom.xml +++ b/lemon-demo-jpa/pom.xml @@ -14,7 +14,7 @@ com.naturalprogrammer spring-lemon - 1.0.0.M4 + 1.0.0.M5 diff --git a/lemon-demo-jpa/src/main/java/com/naturalprogrammer/spring/lemondemo/controllers/MyController.java b/lemon-demo-jpa/src/main/java/com/naturalprogrammer/spring/lemondemo/controllers/MyController.java index c5d5e8e9..09f1dfe2 100644 --- a/lemon-demo-jpa/src/main/java/com/naturalprogrammer/spring/lemondemo/controllers/MyController.java +++ b/lemon-demo-jpa/src/main/java/com/naturalprogrammer/spring/lemondemo/controllers/MyController.java @@ -7,7 +7,9 @@ import com.naturalprogrammer.spring.lemondemo.entities.User; @RestController -@RequestMapping("/api/core") +@RequestMapping(MyController.BASE_URI) public class MyController extends LemonController { + + public static final String BASE_URI = "/api/core"; } \ No newline at end of file diff --git a/lemon-demo-reactive/pom.xml b/lemon-demo-reactive/pom.xml index a1b52aab..d6356b2e 100644 --- a/lemon-demo-reactive/pom.xml +++ b/lemon-demo-reactive/pom.xml @@ -13,7 +13,7 @@ com.naturalprogrammer spring-lemon - 1.0.0.M4 + 1.0.0.M5 diff --git a/lemon-demo-reactive/src/main/java/com/naturalprogrammer/spring/lemondemo/controllers/MyController.java b/lemon-demo-reactive/src/main/java/com/naturalprogrammer/spring/lemondemo/controllers/MyController.java index 3aae7ac0..16759291 100644 --- a/lemon-demo-reactive/src/main/java/com/naturalprogrammer/spring/lemondemo/controllers/MyController.java +++ b/lemon-demo-reactive/src/main/java/com/naturalprogrammer/spring/lemondemo/controllers/MyController.java @@ -17,9 +17,11 @@ import reactor.core.publisher.Mono; @RestController -@RequestMapping("/api/core") +@RequestMapping(MyController.BASE_URI) public class MyController extends LemonReactiveController { + public static final String BASE_URI = "/api/core"; + @Override public Mono> signup( @RequestBody @JsonView(UserUtils.SignupInput.class) diff --git a/lemon-demo-reactive/src/main/java/com/naturalprogrammer/spring/lemondemo/domain/User.java b/lemon-demo-reactive/src/main/java/com/naturalprogrammer/spring/lemondemo/domain/User.java index a613e63a..5bd70f99 100644 --- a/lemon-demo-reactive/src/main/java/com/naturalprogrammer/spring/lemondemo/domain/User.java +++ b/lemon-demo-reactive/src/main/java/com/naturalprogrammer/spring/lemondemo/domain/User.java @@ -17,7 +17,7 @@ import lombok.NoArgsConstructor; import lombok.Setter; -@Getter @Setter @NoArgsConstructor +@Getter @Setter @TypeAlias("User") @Document(collection = "usr") public class User extends AbstractMongoUser { @@ -25,25 +25,11 @@ public class User extends AbstractMongoUser { public static final int NAME_MIN = 1; public static final int NAME_MAX = 50; + @Getter @Setter public static class Tag implements Serializable { private static final long serialVersionUID = -2129078111926834670L; - private String name; - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - } - - public User(String email, String password, String name) { - this.email = email; - this.password = password; - this.name = name; } @JsonView(UserUtils.SignupInput.class) diff --git a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/AbstractTests.java b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/AbstractTests.java new file mode 100644 index 00000000..b2f64e76 --- /dev/null +++ b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/AbstractTests.java @@ -0,0 +1,29 @@ +package com.naturalprogrammer.spring.lemondemo; + +import org.junit.Before; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.context.ApplicationContext; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.test.web.reactive.server.WebTestClient; + +@RunWith(SpringRunner.class) +@SpringBootTest({ + "logging.level.com.naturalprogrammer=ERROR", // logging.level.root=ERROR does not work: https://stackoverflow.com/questions/49048298/springboottest-not-overriding-logging-level + "logging.level.org.springframework=ERROR", + "lemon.recaptcha.sitekey=", + "spring.data.mongodb.lemon=lemontest" +}) +public abstract class AbstractTests { + + @Autowired + protected MyTestUtils testUtils; + + @Before + public void initialize() { + + testUtils.initDatabase(); + } + +} diff --git a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/LemonDemoReactiveApplicationTests.java b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/LemonDemoReactiveApplicationTests.java deleted file mode 100644 index 16d1772b..00000000 --- a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/LemonDemoReactiveApplicationTests.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.naturalprogrammer.spring.lemondemo; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.test.context.junit4.SpringRunner; - -@RunWith(SpringRunner.class) -@SpringBootTest -public class LemonDemoReactiveApplicationTests { - - @Test - public void contextLoads() { - } - -} diff --git a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/LoginTests.java b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/LoginTests.java new file mode 100644 index 00000000..1458cfe2 --- /dev/null +++ b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/LoginTests.java @@ -0,0 +1,39 @@ +package com.naturalprogrammer.spring.lemondemo; + +import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.ADMIN_EMAIL; +import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.ADMIN_ID; +import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.ADMIN_PASSWORD; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + +import org.junit.Test; + +public class LoginTests extends AbstractTests { + + @Test + public void testLogin() throws Exception { + + testUtils.loginResponse(ADMIN_EMAIL, ADMIN_PASSWORD) + .expectStatus().isOk() + .expectBody(TestUserDto.class) + .consumeWith(result -> { + + TestUserDto user = result.getResponseBody(); + + assertEquals(ADMIN_ID, user.getId()); + assertNull(user.getPassword()); + assertEquals("admin@example.com", user.getUsername()); + assertEquals("admin@example.com", user.getRoles()); + assertEquals(1, user.getRoles().size()); + assertTrue(user.getRoles().contains("ADMIN")); + assertEquals("Admin 1", user.getTag().getName()); + assertFalse(user.isUnverified()); + assertFalse(user.isBlocked()); + assertTrue(user.isAdmin()); + assertTrue(user.isGoodUser()); + assertTrue(user.isGoodAdmin()); + }); + } +} diff --git a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/MyTestUtils.java b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/MyTestUtils.java new file mode 100644 index 00000000..4f04ed28 --- /dev/null +++ b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/MyTestUtils.java @@ -0,0 +1,107 @@ +package com.naturalprogrammer.spring.lemondemo; + +import static com.naturalprogrammer.spring.lemondemo.controllers.MyController.BASE_URI; +import static org.springframework.web.reactive.function.BodyInserters.fromFormData; + +import java.util.HashMap; +import java.util.Map; + +import org.bson.types.ObjectId; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationContext; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.stereotype.Component; +import org.springframework.test.web.reactive.server.WebTestClient; +import org.springframework.test.web.reactive.server.WebTestClient.ResponseSpec; + +import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; +import com.naturalprogrammer.spring.lemondemo.domain.User; +import com.naturalprogrammer.spring.lemondemo.repositories.UserRepository; + +@Component +public class MyTestUtils { + + public static final ObjectId ADMIN_ID = ObjectId.get(); + public static final ObjectId UNVERIFIED_ADMIN_ID = ObjectId.get(); + public static final ObjectId BLOCKED_ADMIN_ID = ObjectId.get(); + + public static final ObjectId USER_ID = ObjectId.get(); + public static final ObjectId UNVERIFIED_USER_ID = ObjectId.get(); + public static final ObjectId BLOCKED_USER_ID = ObjectId.get(); + + public static final String ADMIN_EMAIL = "admin@example.com"; + public static final String ADMIN_PASSWORD = "admin!"; + + public static final String USER_PASSWORD = "Sanjay99!"; + public static final String UNVERIFIED_USER_EMAIL = "unverifieduser@example.com"; + + public static final Map TOKENS = new HashMap<>(6); + + public static WebTestClient CLIENT; + + @Autowired + private PasswordEncoder passwordEncoder; + + @Autowired + private UserRepository userRepository; + + public MyTestUtils(ApplicationContext context) { + CLIENT = WebTestClient.bindToApplicationContext(context).build(); + } + + public String login(String userName, String password) { + + return loginResponse(userName, password) + .expectStatus().isOk() + .returnResult(TestUserDto.class) + .getResponseHeaders() + .getFirst(LecUtils.TOKEN_RESPONSE_HEADER_NAME); + } + + public ResponseSpec loginResponse(String userName, String password) { + + return CLIENT.post() + .uri(BASE_URI + "/login") + .body(fromFormData("username", userName) + .with("password", password)) + .exchange(); + } + +// @Override +// public void run(String... args) throws Exception { +// +// TOKENS.put(ADMIN_ID, login(ADMIN_EMAIL, ADMIN_PASSWORD)); +// TOKENS.put(UNVERIFIED_ADMIN_ID, login("unverifiedadmin@example.com", ADMIN_PASSWORD)); +// TOKENS.put(BLOCKED_ADMIN_ID, login("blockedadmin@example.com", ADMIN_PASSWORD)); +// TOKENS.put(USER_ID, login("user@example.com", USER_PASSWORD)); +// TOKENS.put(UNVERIFIED_USER_ID, login(UNVERIFIED_USER_EMAIL, USER_PASSWORD)); +// TOKENS.put(BLOCKED_USER_ID, login("blockeduser@example.com", USER_PASSWORD)); +// } +// + public void initDatabase() { + + userRepository.deleteAll().subscribe(v -> { + createUser(ADMIN_ID, ADMIN_EMAIL, ADMIN_PASSWORD, "Admin 1"); + createUser(UNVERIFIED_ADMIN_ID, "unverifiedadmin@example.com", ADMIN_PASSWORD, "Unverified Admin"); + createUser(BLOCKED_ADMIN_ID, "blockedadmin@example.com", ADMIN_PASSWORD, "Blocked Admin"); + createUser(USER_ID, "user@example.com", USER_PASSWORD, "User"); + createUser(UNVERIFIED_USER_ID, UNVERIFIED_USER_EMAIL, USER_PASSWORD, "Unverified User"); + createUser(BLOCKED_USER_ID, "blockeduser@example.com", USER_PASSWORD, "Blocked User"); + }); + } + + private void createUser(ObjectId id, String email, String password, String name) { + + User user = new User(); + user.setId(id); + user.setEmail(email); + user.setPassword(passwordEncoder.encode(password)); + user.setName(name); + user.setCredentialsUpdatedMillis(0L); + user.setVersion(1L); + + userRepository.insert(user).subscribe(u -> { + TOKENS.put(u.getId(), login(u.getEmail(), password)); + }); + } +} diff --git a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/TestUserDto.java b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/TestUserDto.java new file mode 100644 index 00000000..a317f941 --- /dev/null +++ b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/TestUserDto.java @@ -0,0 +1,27 @@ +package com.naturalprogrammer.spring.lemondemo; + +import java.util.HashSet; +import java.util.Set; + +import org.bson.types.ObjectId; + +import com.naturalprogrammer.spring.lemondemo.domain.User.Tag; + +import lombok.Getter; +import lombok.Setter; + +@Getter @Setter +public class TestUserDto { + + private ObjectId id; + private String username; + private String password; + private Set roles = new HashSet(); + private Tag tag; + + private boolean unverified = false; + private boolean blocked = false; + private boolean admin = false; + private boolean goodUser = false; + private boolean goodAdmin = false; +} diff --git a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/UserClient.java b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/UserClient.java new file mode 100644 index 00000000..28da1912 --- /dev/null +++ b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/UserClient.java @@ -0,0 +1,12 @@ +package com.naturalprogrammer.spring.lemondemo; + +import org.springframework.stereotype.Component; + +import com.naturalprogrammer.spring.lemondemo.controllers.MyController; + +@Component +public class UserClient { + + public static String USER_URI = MyController.BASE_URI + "/users"; + +} diff --git a/pom.xml b/pom.xml index 293011e7..082bffd0 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.naturalprogrammer spring-lemon - 1.0.0.M4 + 1.0.0.M5 pom spring-lemon diff --git a/spring-lemon-commons/pom.xml b/spring-lemon-commons/pom.xml index 2c516e5f..3f2a395e 100644 --- a/spring-lemon-commons/pom.xml +++ b/spring-lemon-commons/pom.xml @@ -14,7 +14,7 @@ com.naturalprogrammer spring-lemon - 1.0.0.M4 + 1.0.0.M5 diff --git a/spring-lemon-exceptions/pom.xml b/spring-lemon-exceptions/pom.xml index 195cd838..7bb72c17 100644 --- a/spring-lemon-exceptions/pom.xml +++ b/spring-lemon-exceptions/pom.xml @@ -13,7 +13,7 @@ com.naturalprogrammer spring-lemon - 1.0.0.M4 + 1.0.0.M5 diff --git a/spring-lemon-jpa/pom.xml b/spring-lemon-jpa/pom.xml index f0cd37b6..6ce4d0ef 100644 --- a/spring-lemon-jpa/pom.xml +++ b/spring-lemon-jpa/pom.xml @@ -13,7 +13,7 @@ com.naturalprogrammer spring-lemon - 1.0.0.M4 + 1.0.0.M5 diff --git a/spring-lemon-reactive/pom.xml b/spring-lemon-reactive/pom.xml index 42b2ef6e..ab46496d 100644 --- a/spring-lemon-reactive/pom.xml +++ b/spring-lemon-reactive/pom.xml @@ -13,7 +13,7 @@ com.naturalprogrammer spring-lemon - 1.0.0.M4 + 1.0.0.M5 From a4a6c95e531bd43adf099116668f968409649f28 Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Fri, 20 Jul 2018 22:13:27 +0530 Subject: [PATCH 007/116] First reactive test case passing --- .../spring/lemondemo/domain/User.java | 1 - .../spring/lemondemo/AbstractTests.java | 5 +-- .../spring/lemondemo/LoginTests.java | 1 - .../spring/lemondemo/MyTestUtils.java | 37 ++++++++++++------- .../LemonReactiveController.java | 6 ++- .../lemonreactive/LemonReactiveService.java | 6 ++- 6 files changed, 34 insertions(+), 22 deletions(-) diff --git a/lemon-demo-reactive/src/main/java/com/naturalprogrammer/spring/lemondemo/domain/User.java b/lemon-demo-reactive/src/main/java/com/naturalprogrammer/spring/lemondemo/domain/User.java index 5bd70f99..14b6cd46 100644 --- a/lemon-demo-reactive/src/main/java/com/naturalprogrammer/spring/lemondemo/domain/User.java +++ b/lemon-demo-reactive/src/main/java/com/naturalprogrammer/spring/lemondemo/domain/User.java @@ -14,7 +14,6 @@ import com.naturalprogrammer.spring.lemonreactive.domain.AbstractMongoUser; import lombok.Getter; -import lombok.NoArgsConstructor; import lombok.Setter; @Getter @Setter diff --git a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/AbstractTests.java b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/AbstractTests.java index b2f64e76..643638af 100644 --- a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/AbstractTests.java +++ b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/AbstractTests.java @@ -4,16 +4,14 @@ import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.context.ApplicationContext; import org.springframework.test.context.junit4.SpringRunner; -import org.springframework.test.web.reactive.server.WebTestClient; @RunWith(SpringRunner.class) @SpringBootTest({ "logging.level.com.naturalprogrammer=ERROR", // logging.level.root=ERROR does not work: https://stackoverflow.com/questions/49048298/springboottest-not-overriding-logging-level "logging.level.org.springframework=ERROR", "lemon.recaptcha.sitekey=", - "spring.data.mongodb.lemon=lemontest" + "spring.data.mongodb.database=lemontest" }) public abstract class AbstractTests { @@ -25,5 +23,4 @@ public void initialize() { testUtils.initDatabase(); } - } diff --git a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/LoginTests.java b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/LoginTests.java index 1458cfe2..a4184169 100644 --- a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/LoginTests.java +++ b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/LoginTests.java @@ -25,7 +25,6 @@ public void testLogin() throws Exception { assertEquals(ADMIN_ID, user.getId()); assertNull(user.getPassword()); assertEquals("admin@example.com", user.getUsername()); - assertEquals("admin@example.com", user.getRoles()); assertEquals(1, user.getRoles().size()); assertTrue(user.getRoles().contains("ADMIN")); assertEquals("Admin 1", user.getTag().getName()); diff --git a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/MyTestUtils.java b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/MyTestUtils.java index 4f04ed28..342966fd 100644 --- a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/MyTestUtils.java +++ b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/MyTestUtils.java @@ -3,12 +3,17 @@ import static com.naturalprogrammer.spring.lemondemo.controllers.MyController.BASE_URI; import static org.springframework.web.reactive.function.BodyInserters.fromFormData; +import java.util.Arrays; import java.util.HashMap; +import java.util.HashSet; import java.util.Map; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; import org.bson.types.ObjectId; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationContext; +import org.springframework.data.mongodb.core.MongoTemplate; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.stereotype.Component; import org.springframework.test.web.reactive.server.WebTestClient; @@ -16,10 +21,11 @@ import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; import com.naturalprogrammer.spring.lemondemo.domain.User; -import com.naturalprogrammer.spring.lemondemo.repositories.UserRepository; @Component public class MyTestUtils { + + private static Log log = LogFactory.getLog(MyTestUtils.class); public static final ObjectId ADMIN_ID = ObjectId.get(); public static final ObjectId UNVERIFIED_ADMIN_ID = ObjectId.get(); @@ -43,7 +49,7 @@ public class MyTestUtils { private PasswordEncoder passwordEncoder; @Autowired - private UserRepository userRepository; + private MongoTemplate mongoTemplate; public MyTestUtils(ApplicationContext context) { CLIENT = WebTestClient.bindToApplicationContext(context).build(); @@ -80,17 +86,20 @@ public ResponseSpec loginResponse(String userName, String password) { // public void initDatabase() { - userRepository.deleteAll().subscribe(v -> { - createUser(ADMIN_ID, ADMIN_EMAIL, ADMIN_PASSWORD, "Admin 1"); - createUser(UNVERIFIED_ADMIN_ID, "unverifiedadmin@example.com", ADMIN_PASSWORD, "Unverified Admin"); - createUser(BLOCKED_ADMIN_ID, "blockedadmin@example.com", ADMIN_PASSWORD, "Blocked Admin"); - createUser(USER_ID, "user@example.com", USER_PASSWORD, "User"); - createUser(UNVERIFIED_USER_ID, UNVERIFIED_USER_EMAIL, USER_PASSWORD, "Unverified User"); - createUser(BLOCKED_USER_ID, "blockeduser@example.com", USER_PASSWORD, "Blocked User"); - }); + mongoTemplate.dropCollection("usr"); + log.debug("Creating users ... "); + + createUser(ADMIN_ID, ADMIN_EMAIL, ADMIN_PASSWORD, "Admin 1", "ADMIN"); + createUser(UNVERIFIED_ADMIN_ID, "unverifiedadmin@example.com", ADMIN_PASSWORD, "Unverified Admin", "ADMIN", "UNVERIFIED"); + createUser(BLOCKED_ADMIN_ID, "blockedadmin@example.com", ADMIN_PASSWORD, "Blocked Admin", "ADMIN", "BLOCKED"); + createUser(USER_ID, "user@example.com", USER_PASSWORD, "User"); + createUser(UNVERIFIED_USER_ID, UNVERIFIED_USER_EMAIL, USER_PASSWORD, "Unverified User", "UNVERIFIED"); + createUser(BLOCKED_USER_ID, "blockeduser@example.com", USER_PASSWORD, "Blocked User", "BLOCKED"); + + log.debug("Created users."); } - private void createUser(ObjectId id, String email, String password, String name) { + private void createUser(ObjectId id, String email, String password, String name, String... roles) { User user = new User(); user.setId(id); @@ -99,9 +108,9 @@ private void createUser(ObjectId id, String email, String password, String name) user.setName(name); user.setCredentialsUpdatedMillis(0L); user.setVersion(1L); + user.setRoles(new HashSet(Arrays.asList(roles))); - userRepository.insert(user).subscribe(u -> { - TOKENS.put(u.getId(), login(u.getEmail(), password)); - }); + mongoTemplate.insert(user); + TOKENS.put(user.getId(), login(user.getEmail(), password)); } } diff --git a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveController.java b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveController.java index d0c9f7ac..7b75a71b 100644 --- a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveController.java +++ b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveController.java @@ -74,7 +74,11 @@ public Mono> login(ServerWebExchange exchange) { Mono>> currentUser = LerUtils.currentUser(); return lemonReactiveService.userWithToken( - currentUser.map(Optional::get), exchange.getResponse(), expirationMillis); + currentUser.map(optionalUser -> { + UserDto user = optionalUser.get(); + user.setPassword(null); + return user; + }), exchange.getResponse(), expirationMillis); } diff --git a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveService.java b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveService.java index 91f2ae91..83e084ca 100644 --- a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveService.java +++ b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveService.java @@ -95,8 +95,12 @@ public void onStartup() { .findByUsername(properties.getAdmin().getUsername()) // Check if the user already exists .doOnError(e -> e instanceof UsernameNotFoundException, e -> { // Doesn't exist. So, create it. + log.debug("Creating first admin ... "); U user = createAdminUser(); - userRepository.insert(user).subscribe(); + userRepository.insert(user).doOnError(err -> { + log.warn("Error creating initial admin " + err); + }).subscribe(); + log.debug("Created first admin."); }).subscribe(); } From 2c0f5fc128247172f1adc7440016b7946eba0d1e Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Sat, 21 Jul 2018 08:56:23 +0530 Subject: [PATCH 008/116] Refined login controller code for credential erasing --- .../LemonReactiveController.java | 21 ++++++++++++------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveController.java b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveController.java index 7b75a71b..c313e62b 100644 --- a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveController.java +++ b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveController.java @@ -12,6 +12,9 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.server.reactive.ServerHttpResponse; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.ReactiveSecurityContextHolder; +import org.springframework.security.core.context.SecurityContext; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PatchMapping; import org.springframework.web.bind.annotation.PathVariable; @@ -25,10 +28,10 @@ import com.naturalprogrammer.spring.lemon.commons.domain.ChangePasswordForm; import com.naturalprogrammer.spring.lemon.commons.domain.ResetPasswordForm; import com.naturalprogrammer.spring.lemon.commons.security.JwtService; +import com.naturalprogrammer.spring.lemon.commons.security.LemonPrincipal; import com.naturalprogrammer.spring.lemon.commons.security.UserDto; import com.naturalprogrammer.spring.lemonreactive.domain.AbstractMongoUser; import com.naturalprogrammer.spring.lemonreactive.forms.EmailForm; -import com.naturalprogrammer.spring.lemonreactive.util.LerUtils; import reactor.core.publisher.Mono; @@ -72,13 +75,15 @@ public Mono> login(ServerWebExchange exchange) { log.debug("Returning current user ... "); long expirationMillis = exchange.getAttributeOrDefault("expirationMillis", jwtExpirationMillis); - Mono>> currentUser = LerUtils.currentUser(); - return lemonReactiveService.userWithToken( - currentUser.map(optionalUser -> { - UserDto user = optionalUser.get(); - user.setPassword(null); - return user; - }), exchange.getResponse(), expirationMillis); + Mono> currentUser = + ReactiveSecurityContextHolder.getContext() + .map(SecurityContext::getAuthentication) + .map(Authentication::getPrincipal) + .cast(LemonPrincipal.class) + .doOnNext(LemonPrincipal::eraseCredentials) + .map(LemonPrincipal::currentUser); + + return lemonReactiveService.userWithToken(currentUser, exchange.getResponse(), expirationMillis); } From e9811ca37ec42542fefe558d2c05313dbcd5f5cc Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Sat, 21 Jul 2018 11:21:24 +0530 Subject: [PATCH 009/116] Changed JWT errors from 403 to 401 --- .../spring/lemondemo/ChangeEmailMvcTests.java | 4 +-- .../lemondemo/VerificationMvcTests.java | 6 ++-- .../spring/lemondemo/AbstractTests.java | 2 +- .../spring/lemondemo/LoginTests.java | 35 ++++++++++++++++++- .../LemonCommonsAutoConfiguration.java | 4 +++ .../lemon/commons/security/JwtService.java | 16 +++++++-- .../commons}/security/JwtServiceTests.java | 9 +++-- .../spring/lemon/LemonAutoConfiguration.java | 4 +-- .../LemonReactiveAutoConfiguration.java | 3 +- .../LemonReactiveController.java | 15 ++++---- .../lemonreactive/LemonReactiveService.java | 16 ++++++--- .../spring/lemonreactive/util/LerUtils.java | 3 ++ 12 files changed, 88 insertions(+), 29 deletions(-) rename {spring-lemon-jpa/src/test/java/com/naturalprogrammer/spring/lemon => spring-lemon-commons/src/test/java/com/naturalprogrammer/lemon/commons}/security/JwtServiceTests.java (85%) diff --git a/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/ChangeEmailMvcTests.java b/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/ChangeEmailMvcTests.java index 927fdd65..c1c371ca 100644 --- a/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/ChangeEmailMvcTests.java +++ b/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/ChangeEmailMvcTests.java @@ -84,7 +84,7 @@ public void testChangeEmailWrongCode() throws Exception { .param("code", code) .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, tokens.get(UNVERIFIED_USER_ID)) .header("contentType", MediaType.APPLICATION_FORM_URLENCODED)) - .andExpect(status().is(403)); + .andExpect(status().is(401)); // Wrong userId subject code = jwtService.createToken( @@ -131,7 +131,7 @@ public void testChangeEmailObsoleteCode() throws Exception { .param("code", changeEmailCode) .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, authToken) .header("contentType", MediaType.APPLICATION_FORM_URLENCODED)) - .andExpect(status().is(403)); + .andExpect(status().is(401)); } /** diff --git a/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/VerificationMvcTests.java b/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/VerificationMvcTests.java index f360e8f4..4d101276 100644 --- a/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/VerificationMvcTests.java +++ b/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/VerificationMvcTests.java @@ -82,7 +82,7 @@ public void testEmailVerificationWrongToken() throws Exception { mvc.perform(post("/api/core/users/{userId}/verification", UNVERIFIED_USER_ID) .param("code", token) .header("contentType", MediaType.APPLICATION_FORM_URLENCODED)) - .andExpect(status().is(403)); + .andExpect(status().is(401)); // Wrong email token = jwtService.createToken(JwtService.VERIFY_AUDIENCE, @@ -101,7 +101,7 @@ public void testEmailVerificationWrongToken() throws Exception { mvc.perform(post("/api/core/users/{userId}/verification", UNVERIFIED_USER_ID) .param("code", token) .header("contentType", MediaType.APPLICATION_FORM_URLENCODED)) - .andExpect(status().is(403)); + .andExpect(status().is(401)); } @Test @@ -116,6 +116,6 @@ public void testEmailVerificationAfterCredentialsUpdate() throws Exception { mvc.perform(post("/api/core/users/{userId}/verification", UNVERIFIED_USER_ID) .param("code", verificationCode) .header("contentType", MediaType.APPLICATION_FORM_URLENCODED)) - .andExpect(status().is(403)); + .andExpect(status().is(401)); } } diff --git a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/AbstractTests.java b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/AbstractTests.java index 643638af..a95895d5 100644 --- a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/AbstractTests.java +++ b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/AbstractTests.java @@ -8,7 +8,7 @@ @RunWith(SpringRunner.class) @SpringBootTest({ - "logging.level.com.naturalprogrammer=ERROR", // logging.level.root=ERROR does not work: https://stackoverflow.com/questions/49048298/springboottest-not-overriding-logging-level + "logging.level.com.naturalprogrammer=DEBUG", // logging.level.root=ERROR does not work: https://stackoverflow.com/questions/49048298/springboottest-not-overriding-logging-level "logging.level.org.springframework=ERROR", "lemon.recaptcha.sitekey=", "spring.data.mongodb.database=lemontest" diff --git a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/LoginTests.java b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/LoginTests.java index a4184169..e1d65149 100644 --- a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/LoginTests.java +++ b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/LoginTests.java @@ -3,17 +3,22 @@ import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.ADMIN_EMAIL; import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.ADMIN_ID; import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.ADMIN_PASSWORD; +import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.CLIENT; +import static com.naturalprogrammer.spring.lemondemo.controllers.MyController.BASE_URI; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; +import static org.springframework.web.reactive.function.BodyInserters.fromFormData; import org.junit.Test; +import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; + public class LoginTests extends AbstractTests { @Test - public void testLogin() throws Exception { + public void testLogin() { testUtils.loginResponse(ADMIN_EMAIL, ADMIN_PASSWORD) .expectStatus().isOk() @@ -35,4 +40,32 @@ public void testLogin() throws Exception { assertTrue(user.isGoodAdmin()); }); } + + + @Test + public void testLoginTokenExpiry() throws Exception { + + String token = login(ADMIN_EMAIL, ADMIN_PASSWORD, 500L); + Thread.sleep(501L); + + CLIENT.get() + .uri("/api/core/ping") + .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, token) + .exchange() + .expectStatus().isUnauthorized(); + } + + + private String login(String username, String password, long expirationMillis) { + + return CLIENT.post() + .uri(BASE_URI + "/login") + .body(fromFormData("username", username) + .with("password", password) + .with("expirationMillis", Long.toString(expirationMillis))) + .exchange() + .returnResult(TestUserDto.class) + .getResponseHeaders() + .getFirst(LecUtils.TOKEN_RESPONSE_HEADER_NAME); + } } diff --git a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/LemonCommonsAutoConfiguration.java b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/LemonCommonsAutoConfiguration.java index 688eb572..a09563df 100644 --- a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/LemonCommonsAutoConfiguration.java +++ b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/LemonCommonsAutoConfiguration.java @@ -2,6 +2,7 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.springframework.boot.autoconfigure.AutoConfigureBefore; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.context.annotation.Bean; @@ -21,11 +22,14 @@ import com.naturalprogrammer.spring.lemon.commons.security.JwtService; import com.naturalprogrammer.spring.lemon.commons.security.LemonPermissionEvaluator; import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; +import com.naturalprogrammer.spring.lemon.exceptions.LemonExceptionsAutoConfiguration; import com.nimbusds.jose.KeyLengthException; @Configuration @ComponentScan(basePackageClasses=BadCredentialsExceptionHandler.class) @EnableAsync +@AutoConfigureBefore({ + LemonExceptionsAutoConfiguration.class}) public class LemonCommonsAutoConfiguration { private static final Log log = LogFactory.getLog(LemonCommonsAutoConfiguration.class); diff --git a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/JwtService.java b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/JwtService.java index ac268ce2..56705111 100644 --- a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/JwtService.java +++ b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/JwtService.java @@ -5,6 +5,8 @@ import java.util.HashMap; import java.util.Map; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; import org.springframework.security.authentication.BadCredentialsException; import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; @@ -36,6 +38,8 @@ */ public class JwtService { + private static final Log log = LogFactory.getLog(JwtService.class); + public static final String LEMON_IAT = "lemon-iat"; public static final String AUTH_AUDIENCE = "auth"; public static final String VERIFY_AUDIENCE = "verify"; @@ -115,11 +119,17 @@ public JWTClaimsSet parseToken(String token, String audience) { try { JWTClaimsSet claims = jwtProcessor.process(token, null); - LecUtils.ensureAuthority(audience != null && + LecUtils.ensureCredentials(audience != null && claims.getAudience().contains(audience), "com.naturalprogrammer.spring.wrong.audience"); - LecUtils.ensureAuthority(claims.getExpirationTime().after(new Date()), + long expirationTime = claims.getExpirationTime().getTime(); + long currentTime = System.currentTimeMillis(); + + log.debug("Parsing JWT. Expiration time = " + expirationTime + + ". Current time = " + currentTime); + + LecUtils.ensureCredentials(expirationTime >= currentTime, "com.naturalprogrammer.spring.expiredToken"); return claims; @@ -138,7 +148,7 @@ public JWTClaimsSet parseToken(String token, String audience, long issuedAfter) JWTClaimsSet claims = parseToken(token, audience); long issueTime = (long) claims.getClaim(LEMON_IAT); - LecUtils.ensureAuthority(issueTime >= issuedAfter, + LecUtils.ensureCredentials(issueTime >= issuedAfter, "com.naturalprogrammer.spring.obsoleteToken"); return claims; diff --git a/spring-lemon-jpa/src/test/java/com/naturalprogrammer/spring/lemon/security/JwtServiceTests.java b/spring-lemon-commons/src/test/java/com/naturalprogrammer/lemon/commons/security/JwtServiceTests.java similarity index 85% rename from spring-lemon-jpa/src/test/java/com/naturalprogrammer/spring/lemon/security/JwtServiceTests.java rename to spring-lemon-commons/src/test/java/com/naturalprogrammer/lemon/commons/security/JwtServiceTests.java index 2dc58133..a2d46853 100644 --- a/spring-lemon-jpa/src/test/java/com/naturalprogrammer/spring/lemon/security/JwtServiceTests.java +++ b/spring-lemon-commons/src/test/java/com/naturalprogrammer/lemon/commons/security/JwtServiceTests.java @@ -1,8 +1,7 @@ -package com.naturalprogrammer.spring.lemon.security; +package com.naturalprogrammer.lemon.commons.security; import org.junit.Assert; import org.junit.Test; -import org.springframework.security.access.AccessDeniedException; import org.springframework.security.authentication.BadCredentialsException; import com.naturalprogrammer.spring.lemon.commons.security.JwtService; @@ -36,14 +35,14 @@ public void testJwtParseToken() { Assert.assertEquals("abc@example.com", claims.getClaim("username")); } - @Test(expected = AccessDeniedException.class) + @Test(expected = BadCredentialsException.class) public void testJwtParseTokenWrongAudience() { String token = service1.createToken("auth", "subject", 5000L); service1.parseToken(token, "auth2"); } - @Test(expected = AccessDeniedException.class) + @Test(expected = BadCredentialsException.class) public void testJwtParseTokenExpired() throws InterruptedException { String token = service1.createToken("auth", "subject", 1L); @@ -58,7 +57,7 @@ public void testJwtParseTokenWrongSecret() { service2.parseToken(token, "auth"); } - @Test(expected = AccessDeniedException.class) + @Test(expected = BadCredentialsException.class) public void testParseTokenCutoffTime() throws InterruptedException { String token = service1.createToken("auth", "subject", 5000L); diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/LemonAutoConfiguration.java b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/LemonAutoConfiguration.java index 29270a2b..3f99909e 100644 --- a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/LemonAutoConfiguration.java +++ b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/LemonAutoConfiguration.java @@ -32,6 +32,7 @@ import org.springframework.transaction.annotation.EnableTransactionManagement; import com.fasterxml.jackson.databind.ObjectMapper; +import com.naturalprogrammer.spring.lemon.commons.LemonCommonsAutoConfiguration; import com.naturalprogrammer.spring.lemon.commons.LemonProperties; import com.naturalprogrammer.spring.lemon.commons.security.JwtService; import com.naturalprogrammer.spring.lemon.commons.validation.RetypePasswordValidator; @@ -42,7 +43,6 @@ import com.naturalprogrammer.spring.lemon.exceptions.ErrorResponseComposer; import com.naturalprogrammer.spring.lemon.exceptions.LemonErrorAttributes; import com.naturalprogrammer.spring.lemon.exceptions.LemonErrorController; -import com.naturalprogrammer.spring.lemon.exceptions.LemonExceptionsAutoConfiguration; import com.naturalprogrammer.spring.lemon.security.AuthenticationSuccessHandler; import com.naturalprogrammer.spring.lemon.security.JwtAuthenticationProvider; import com.naturalprogrammer.spring.lemon.security.LemonCorsConfig; @@ -71,7 +71,7 @@ ErrorMvcAutoConfiguration.class, SecurityAutoConfiguration.class, SecurityFilterAutoConfiguration.class, - LemonExceptionsAutoConfiguration.class}) + LemonCommonsAutoConfiguration.class}) public class LemonAutoConfiguration { /** diff --git a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveAutoConfiguration.java b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveAutoConfiguration.java index 049da887..16accf80 100644 --- a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveAutoConfiguration.java +++ b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveAutoConfiguration.java @@ -9,7 +9,6 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.security.reactive.ReactiveSecurityAutoConfiguration; import org.springframework.boot.autoconfigure.security.reactive.ReactiveUserDetailsServiceAutoConfiguration; -import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration; import org.springframework.boot.autoconfigure.web.reactive.WebFluxAutoConfiguration; import org.springframework.boot.autoconfigure.web.reactive.error.ErrorWebFluxAutoConfiguration; import org.springframework.boot.web.reactive.error.ErrorAttributes; @@ -44,7 +43,7 @@ @AutoConfigureBefore({ WebFluxAutoConfiguration.class, ErrorWebFluxAutoConfiguration.class, - SecurityAutoConfiguration.class, +// SecurityAutoConfiguration.class, ReactiveSecurityAutoConfiguration.class, ReactiveUserDetailsServiceAutoConfiguration.class, LemonCommonsAutoConfiguration.class}) diff --git a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveController.java b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveController.java index c313e62b..e900a0ab 100644 --- a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveController.java +++ b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveController.java @@ -34,6 +34,7 @@ import com.naturalprogrammer.spring.lemonreactive.forms.EmailForm; import reactor.core.publisher.Mono; +import reactor.util.function.Tuple2; /** * The Lemon Mongo API. See the @@ -73,17 +74,19 @@ public void createLemonController( public Mono> login(ServerWebExchange exchange) { log.debug("Returning current user ... "); - long expirationMillis = exchange.getAttributeOrDefault("expirationMillis", jwtExpirationMillis); - Mono> currentUser = - ReactiveSecurityContextHolder.getContext() + return ReactiveSecurityContextHolder.getContext() .map(SecurityContext::getAuthentication) .map(Authentication::getPrincipal) .cast(LemonPrincipal.class) .doOnNext(LemonPrincipal::eraseCredentials) - .map(LemonPrincipal::currentUser); - - return lemonReactiveService.userWithToken(currentUser, exchange.getResponse(), expirationMillis); + .map(LemonPrincipal::currentUser) + .zipWith(exchange.getFormData()) + .doOnNext(tuple -> { + long expirationMillis = lemonReactiveService.getExpirationMillis(tuple.getT2()); + lemonReactiveService.addAuthHeader(exchange.getResponse(), tuple.getT1(), expirationMillis); + }) + .map(Tuple2::getT1); } diff --git a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveService.java b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveService.java index 83e084ca..b0e1591e 100644 --- a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveService.java +++ b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveService.java @@ -776,10 +776,7 @@ public Mono> fetchNewToken(ServerWebExchange exchange) { if (StringUtils.isNotBlank(username)) username = currentUser.getUsername(); - long expirationMillis = properties.getJwt().getExpirationMillis(); - String expirationMillisStr = tuple.getT2().getFirst("expirationMillis"); - if (StringUtils.isNotBlank(expirationMillisStr)) - expirationMillis = Long.parseLong(expirationMillisStr); + long expirationMillis = getExpirationMillis(tuple.getT2()); LecUtils.ensureAuthority(currentUser.getUsername().equals(username) || currentUser.isGoodAdmin(), "com.naturalprogrammer.spring.notGoodAdminOrSameUser"); @@ -788,4 +785,15 @@ public Mono> fetchNewToken(ServerWebExchange exchange) { jwtService.createToken(JwtService.AUTH_AUDIENCE, username, expirationMillis)); }); } + + + public long getExpirationMillis(MultiValueMap formData) { + + long expirationMillis = properties.getJwt().getExpirationMillis(); + String expirationMillisStr = formData.getFirst("expirationMillis"); + if (StringUtils.isNotBlank(expirationMillisStr)) + expirationMillis = Long.parseLong(expirationMillisStr); + + return expirationMillis; + } } diff --git a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/util/LerUtils.java b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/util/LerUtils.java index 37c38a0c..ba537b54 100644 --- a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/util/LerUtils.java +++ b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/util/LerUtils.java @@ -61,6 +61,9 @@ void ensureCredentialsUpToDate(JWTClaimsSet claims, U user) { long issueTime = (long) claims.getClaim(JwtService.LEMON_IAT); + log.debug("Ensuring credentials up to date. Issue time = " + + issueTime + ". User's credentials updated at" + user.getCredentialsUpdatedMillis()); + LecUtils.ensureCredentials(issueTime >= user.getCredentialsUpdatedMillis(), "com.naturalprogrammer.spring.obsoleteToken"); } From 41121990dfa4bc96f7c6790638d799927ff4377a Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Sat, 21 Jul 2018 11:42:55 +0530 Subject: [PATCH 010/116] Login tests coded --- .../spring/lemondemo/AbstractTests.java | 4 ++ .../spring/lemondemo/LoginTests.java | 68 +++++++++++++++++++ .../spring/lemondemo/MyTestUtils.java | 1 + .../security/LemonReactiveSecurityConfig.java | 3 +- 4 files changed, 75 insertions(+), 1 deletion(-) diff --git a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/AbstractTests.java b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/AbstractTests.java index a95895d5..c078f54a 100644 --- a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/AbstractTests.java +++ b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/AbstractTests.java @@ -4,6 +4,7 @@ import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.data.mongodb.core.MongoTemplate; import org.springframework.test.context.junit4.SpringRunner; @RunWith(SpringRunner.class) @@ -15,6 +16,9 @@ }) public abstract class AbstractTests { + @Autowired + protected MongoTemplate mongoTemplate; + @Autowired protected MyTestUtils testUtils; diff --git a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/LoginTests.java b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/LoginTests.java index e1d65149..68191618 100644 --- a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/LoginTests.java +++ b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/LoginTests.java @@ -4,16 +4,22 @@ import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.ADMIN_ID; import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.ADMIN_PASSWORD; import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.CLIENT; +import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.TOKENS; import static com.naturalprogrammer.spring.lemondemo.controllers.MyController.BASE_URI; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; import static org.springframework.web.reactive.function.BodyInserters.fromFormData; import org.junit.Test; import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; +import com.naturalprogrammer.spring.lemondemo.domain.User; public class LoginTests extends AbstractTests { @@ -56,6 +62,68 @@ public void testLoginTokenExpiry() throws Exception { } + @Test + public void testObsoleteToken() throws Exception { + + User user = mongoTemplate.findById(ADMIN_ID, User.class); + user.setCredentialsUpdatedMillis(System.currentTimeMillis()); + mongoTemplate.save(user); + + CLIENT.get() + .uri("/api/core/ping") + .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, TOKENS.get(ADMIN_ID)) + .exchange() + .expectStatus().isUnauthorized(); + } + + + @Test + public void testLoginWrongPassword() throws Exception { + + testUtils.loginResponse(ADMIN_EMAIL, "wrong-password") + .expectStatus().isUnauthorized(); + } + + + @Test + public void testLoginBlankPassword() throws Exception { + + testUtils.loginResponse(ADMIN_EMAIL, "") + .expectStatus().isUnauthorized(); + } + + + @Test + public void testTokenLogin() { + + CLIENT.get().uri("/api/core/context") + .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, TOKENS.get(ADMIN_ID)) + .exchange() + .expectStatus().isOk() + .expectBody() + .jsonPath("$.user.id").isEqualTo(ADMIN_ID.toString()); + } + + + @Test + public void testTokenLoginWrongToken() { + + CLIENT.get().uri("/api/core/context") + .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, "Bearer a-wrong-token") + .exchange() + .expectStatus().isUnauthorized(); + } + + + @Test + public void testLogout() throws Exception { + + CLIENT.post().uri("/logout") + .exchange() + .expectStatus().isNotFound(); + } + + private String login(String username, String password, long expirationMillis) { return CLIENT.post() diff --git a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/MyTestUtils.java b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/MyTestUtils.java index 342966fd..30169ab3 100644 --- a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/MyTestUtils.java +++ b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/MyTestUtils.java @@ -99,6 +99,7 @@ public void initDatabase() { log.debug("Created users."); } + private void createUser(ObjectId id, String email, String password, String name, String... roles) { User user = new User(); diff --git a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/security/LemonReactiveSecurityConfig.java b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/security/LemonReactiveSecurityConfig.java index fd72f979..97976766 100644 --- a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/security/LemonReactiveSecurityConfig.java +++ b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/security/LemonReactiveSecurityConfig.java @@ -58,7 +58,8 @@ public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) .authenticationEntryPoint(authenticationEntryPoint()) .and() .csrf().disable() - .addFilterAt(tokenAuthenticationFilter(), SecurityWebFiltersOrder.AUTHENTICATION) + .addFilterAt(tokenAuthenticationFilter(), SecurityWebFiltersOrder.AUTHENTICATION) + .logout().disable() .build(); } From 24d24376ea450e2b757d2ebeb8dea37abfe6e82f Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Sat, 21 Jul 2018 16:06:06 +0530 Subject: [PATCH 011/116] Reactive BasicTests coded --- .../spring/lemondemo/BasicTests.java | 52 +++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/BasicTests.java diff --git a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/BasicTests.java b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/BasicTests.java new file mode 100644 index 00000000..dae685e1 --- /dev/null +++ b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/BasicTests.java @@ -0,0 +1,52 @@ +package com.naturalprogrammer.spring.lemondemo; + +import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.ADMIN_ID; +import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.CLIENT; +import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.TOKENS; +import static com.naturalprogrammer.spring.lemondemo.controllers.MyController.BASE_URI; + +import org.junit.Test; + +import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; + +public class BasicTests extends AbstractTests { + + @Test + public void testPing() throws Exception { + + CLIENT.get() + .uri(BASE_URI + "/ping") + .exchange() + .expectStatus() + .isNoContent(); + } + + @Test + public void testGetContextLoggedIn() throws Exception { + + CLIENT.get() + .uri(BASE_URI + "/context") + .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, TOKENS.get(ADMIN_ID)) + .exchange() + .expectStatus().isOk() + .expectHeader().exists(LecUtils.TOKEN_RESPONSE_HEADER_NAME) + .expectBody() + .jsonPath("$.context.reCaptchaSiteKey").exists() + .jsonPath("$.user.id").isEqualTo(ADMIN_ID.toString()) + .jsonPath("$.user.roles[0]").isEqualTo("ADMIN"); + } + + @Test + public void testGetContextWithoutLoggedIn() throws Exception { + + CLIENT.get() + .uri(BASE_URI + "/context") + .exchange() + .expectStatus().isOk() + .expectHeader().doesNotExist(LecUtils.TOKEN_RESPONSE_HEADER_NAME) + .expectBody() + .jsonPath("$.context.reCaptchaSiteKey").exists() + .jsonPath("$.user").doesNotExist(); + } + +} From c71dca9c979d4a0195f59c33a15a06e154dcf381 Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Sat, 21 Jul 2018 16:49:39 +0530 Subject: [PATCH 012/116] Coded reactive ChangeEmailTests --- .../spring/lemondemo/ChangeEmailTests.java | 161 ++++++++++++++++++ .../spring/lemondemo/LoginTests.java | 12 +- 2 files changed, 165 insertions(+), 8 deletions(-) create mode 100644 lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/ChangeEmailTests.java diff --git a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/ChangeEmailTests.java b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/ChangeEmailTests.java new file mode 100644 index 00000000..1ffeaba6 --- /dev/null +++ b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/ChangeEmailTests.java @@ -0,0 +1,161 @@ +package com.naturalprogrammer.spring.lemondemo; + +import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.ADMIN_ID; +import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.CLIENT; +import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.TOKENS; +import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.UNVERIFIED_USER_EMAIL; +import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.UNVERIFIED_USER_ID; +import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.USER_ID; +import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.USER_PASSWORD; +import static com.naturalprogrammer.spring.lemondemo.controllers.MyController.BASE_URI; +import static org.springframework.web.reactive.function.BodyInserters.fromFormData; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.test.web.reactive.server.WebTestClient.ResponseSpec; + +import com.naturalprogrammer.spring.lemon.commons.security.JwtService; +import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; +import com.naturalprogrammer.spring.lemondemo.domain.User; + +public class ChangeEmailTests extends AbstractTests { + + private static final String NEW_EMAIL = "new.email@example.com"; + + private String changeEmailCode; + + @Autowired + private JwtService jwtService; + + @Before + public void setUp() { + + User user = mongoTemplate.findById(UNVERIFIED_USER_ID, User.class); + user.setNewEmail(NEW_EMAIL); + mongoTemplate.save(user); + + changeEmailCode = jwtService.createToken( + JwtService.CHANGE_EMAIL_AUDIENCE, + UNVERIFIED_USER_ID.toString(), 60000L, + LecUtils.mapOf("newEmail", NEW_EMAIL)); + } + + @Test + public void testChangeEmail() throws Exception { + + changeEmailResponse(changeEmailCode) + .expectStatus().isOk() + .expectHeader().valueMatches(LecUtils.TOKEN_RESPONSE_HEADER_NAME, ".*\\..*") + .expectBody().jsonPath("$.id").isEqualTo(UNVERIFIED_USER_ID.toString()); + + User updatedUser = mongoTemplate.findById(UNVERIFIED_USER_ID, User.class); + Assert.assertNull(updatedUser.getNewEmail()); + Assert.assertEquals(NEW_EMAIL, updatedUser.getEmail()); + + changeEmailResponse(changeEmailCode) + .expectStatus().isUnauthorized(); + } + + /** + * Providing a wrong changeEmailCode shouldn't work. + */ + @Test + public void testChangeEmailWrongCode() throws Exception { + + // Blank token + changeEmailResponse("") + .expectStatus().isEqualTo(HttpStatus.UNPROCESSABLE_ENTITY); + + // Wrong audience + String code = jwtService.createToken( + "", // blank audience + UNVERIFIED_USER_ID.toString(), 60000L, + LecUtils.mapOf("newEmail", NEW_EMAIL)); + + changeEmailResponse(code) + .expectStatus().isUnauthorized(); + + // Wrong userId subject + code = jwtService.createToken( + JwtService.CHANGE_EMAIL_AUDIENCE, + ADMIN_ID.toString(), 60000L, + LecUtils.mapOf("newEmail", NEW_EMAIL)); + + changeEmailResponse(code) + .expectStatus().isForbidden(); + + // Wrong new email + code = jwtService.createToken( + JwtService.CHANGE_EMAIL_AUDIENCE, + UNVERIFIED_USER_ID.toString(), 60000L, + LecUtils.mapOf("newEmail", "wrong.new.email@example.com")); + + changeEmailResponse(code) + .expectStatus().isForbidden(); + } + + /** + * Providing a wrong changeEmailCode shouldn't work. + */ + @Test + public void testChangeEmailObsoleteCode() throws Exception { + + // credentials updated after the request for email change was made + Thread.sleep(1L); + User user = mongoTemplate.findById(UNVERIFIED_USER_ID, User.class); + user.setCredentialsUpdatedMillis(System.currentTimeMillis()); + mongoTemplate.save(user); + + // A new auth token is needed, because old one would be obsolete! + String authToken = testUtils.login(UNVERIFIED_USER_EMAIL, USER_PASSWORD); + + CLIENT.post().uri(BASE_URI + "/users/{id}/email", UNVERIFIED_USER_ID) + .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, authToken) + .body(fromFormData("code", changeEmailCode)) + .exchange() + .expectStatus().isUnauthorized(); + } + + /** + * Trying without having requested first. + * @throws Exception + */ + @Test + public void testChangeEmailWithoutAnyRequest() throws Exception { + + CLIENT.post().uri(BASE_URI + "/users/{id}/email", USER_ID) + .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, TOKENS.get(USER_ID)) + .body(fromFormData("code", changeEmailCode)) + .exchange() + .expectStatus().isEqualTo(HttpStatus.UNPROCESSABLE_ENTITY); + } + + /** + * Trying after some user registers the newEmail, leaving it non unique. + * @throws Exception + */ + @Test + public void testChangeEmailNonUniqueEmail() throws Exception { + + // Some other user changed to the same email + User user = mongoTemplate.findById(ADMIN_ID, User.class); + user.setEmail(NEW_EMAIL); + mongoTemplate.save(user); + + // Blank token + changeEmailResponse(changeEmailCode) + .expectStatus().isEqualTo(HttpStatus.UNPROCESSABLE_ENTITY); + } + + private ResponseSpec changeEmailResponse(String code) { + + return CLIENT.post().uri(BASE_URI + "/users/{id}/email", UNVERIFIED_USER_ID) + .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, TOKENS.get(UNVERIFIED_USER_ID)) + .body(fromFormData("code", code)) + .exchange(); + } + +} diff --git a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/LoginTests.java b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/LoginTests.java index 68191618..82e2ac22 100644 --- a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/LoginTests.java +++ b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/LoginTests.java @@ -10,10 +10,6 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; import static org.springframework.web.reactive.function.BodyInserters.fromFormData; import org.junit.Test; @@ -55,7 +51,7 @@ public void testLoginTokenExpiry() throws Exception { Thread.sleep(501L); CLIENT.get() - .uri("/api/core/ping") + .uri(BASE_URI + "/ping") .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, token) .exchange() .expectStatus().isUnauthorized(); @@ -70,7 +66,7 @@ public void testObsoleteToken() throws Exception { mongoTemplate.save(user); CLIENT.get() - .uri("/api/core/ping") + .uri(BASE_URI + "/ping") .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, TOKENS.get(ADMIN_ID)) .exchange() .expectStatus().isUnauthorized(); @@ -96,7 +92,7 @@ public void testLoginBlankPassword() throws Exception { @Test public void testTokenLogin() { - CLIENT.get().uri("/api/core/context") + CLIENT.get().uri(BASE_URI + "/context") .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, TOKENS.get(ADMIN_ID)) .exchange() .expectStatus().isOk() @@ -108,7 +104,7 @@ public void testTokenLogin() { @Test public void testTokenLoginWrongToken() { - CLIENT.get().uri("/api/core/context") + CLIENT.get().uri(BASE_URI + "/context") .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, "Bearer a-wrong-token") .exchange() .expectStatus().isUnauthorized(); From ad820de640f4ed419ba6d8432a5c3c220dbbbb8f Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Sat, 21 Jul 2018 21:50:04 +0530 Subject: [PATCH 013/116] Coded Reactive ChangePasswordTests --- .../lemondemo/ChangePasswordMvcTests.java | 1 + .../spring/lemondemo/AbstractTests.java | 21 ++ .../spring/lemondemo/ChangePasswordTests.java | 201 ++++++++++++++++++ .../lemon/exceptions/LemonFieldError.java | 24 +-- 4 files changed, 228 insertions(+), 19 deletions(-) create mode 100644 lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/ChangePasswordTests.java diff --git a/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/ChangePasswordMvcTests.java b/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/ChangePasswordMvcTests.java index f5d43085..6804ab4c 100644 --- a/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/ChangePasswordMvcTests.java +++ b/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/ChangePasswordMvcTests.java @@ -142,6 +142,7 @@ public void testChangePasswordInvalidData() throws Exception { "changePasswordForm.retypePassword", "changePasswordForm.password"))); + // different retype-password form = changePasswordForm(USER_PASSWORD); form.setRetypePassword("different-retype-password"); diff --git a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/AbstractTests.java b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/AbstractTests.java index c078f54a..12d6110f 100644 --- a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/AbstractTests.java +++ b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/AbstractTests.java @@ -1,11 +1,21 @@ package com.naturalprogrammer.spring.lemondemo; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.util.Arrays; +import java.util.stream.Collectors; + import org.junit.Before; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.data.mongodb.core.MongoTemplate; import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.test.web.reactive.server.EntityExchangeResult; + +import com.naturalprogrammer.spring.lemon.exceptions.ErrorResponse; +import com.naturalprogrammer.spring.lemon.exceptions.LemonFieldError; @RunWith(SpringRunner.class) @SpringBootTest({ @@ -27,4 +37,15 @@ public void initialize() { testUtils.initDatabase(); } + + + protected void assertErrors(EntityExchangeResult errorResponseResult, String... fields) { + + ErrorResponse response = errorResponseResult.getResponseBody(); + assertEquals(fields.length, response.getErrors().size()); + + assertTrue(response.getErrors().stream() + .map(LemonFieldError::getField).collect(Collectors.toSet()) + .containsAll(Arrays.asList(fields))); + } } diff --git a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/ChangePasswordTests.java b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/ChangePasswordTests.java new file mode 100644 index 00000000..8b31ba4e --- /dev/null +++ b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/ChangePasswordTests.java @@ -0,0 +1,201 @@ +package com.naturalprogrammer.spring.lemondemo; + +import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.ADMIN_ID; +import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.ADMIN_PASSWORD; +import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.CLIENT; +import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.TOKENS; +import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.UNVERIFIED_ADMIN_ID; +import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.UNVERIFIED_USER_EMAIL; +import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.UNVERIFIED_USER_ID; +import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.USER_ID; +import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.USER_PASSWORD; +import static com.naturalprogrammer.spring.lemondemo.controllers.MyController.BASE_URI; + +import org.bson.types.ObjectId; +import org.junit.Test; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; + +import com.naturalprogrammer.spring.lemon.commons.domain.ChangePasswordForm; +import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; +import com.naturalprogrammer.spring.lemon.exceptions.ErrorResponse; + +import reactor.core.publisher.Mono; + +public class ChangePasswordTests extends AbstractTests { + + private static final String NEW_PASSWORD = "a-new-password"; + + private ChangePasswordForm changePasswordForm(String oldPassword) { + + ChangePasswordForm form = new ChangePasswordForm(); + form.setOldPassword(oldPassword); + form.setPassword(NEW_PASSWORD); + form.setRetypePassword(NEW_PASSWORD); + + return form; + } + + /** + * A non-admin user should be able to change his password. + */ + @Test + public void testChangePassword() throws Exception { + + CLIENT.post().uri(BASE_URI + "/users/{id}/password", UNVERIFIED_USER_ID) + .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, TOKENS.get(UNVERIFIED_USER_ID)) + .contentType(MediaType.APPLICATION_JSON) + .body(Mono.just(changePasswordForm(USER_PASSWORD)), ChangePasswordForm.class) + .exchange() + .expectStatus().isNoContent() + .expectHeader().exists(LecUtils.TOKEN_RESPONSE_HEADER_NAME); + + // Ensure able to login with new password + testUtils.login(UNVERIFIED_USER_EMAIL, NEW_PASSWORD); + } + + + /** + * An good admin user should be able to change the password of another user. + */ + @Test + public void testAdminChangePasswordAnotherUser() throws Exception { + + CLIENT.post().uri(BASE_URI + "/users/{id}/password", UNVERIFIED_USER_ID) + .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, TOKENS.get(ADMIN_ID)) + .contentType(MediaType.APPLICATION_JSON) + .body(Mono.just(changePasswordForm(ADMIN_PASSWORD)), ChangePasswordForm.class) + .exchange() + .expectStatus().isNoContent() + .expectHeader().exists(LecUtils.TOKEN_RESPONSE_HEADER_NAME); + + // Ensure able to login with new password + testUtils.login(UNVERIFIED_USER_EMAIL, NEW_PASSWORD); + } + + /** + * Providing an unknown id should return 404. + */ + @Test + public void testChangePasswordUnknownId() throws Exception { + + CLIENT.post().uri(BASE_URI + "/users/{id}/password", ObjectId.get()) + .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, TOKENS.get(ADMIN_ID)) + .contentType(MediaType.APPLICATION_JSON) + .body(Mono.just(changePasswordForm(ADMIN_PASSWORD)), ChangePasswordForm.class) + .exchange() + .expectStatus().isNotFound() + .expectHeader().doesNotExist(LecUtils.TOKEN_RESPONSE_HEADER_NAME); + } + + /** + * A non-admin user should not be able to change others' password. + */ + @Test + public void testChangePasswordAnotherUser() throws Exception { + + CLIENT.post().uri(BASE_URI + "/users/{id}/password", UNVERIFIED_USER_ID) + .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, TOKENS.get(USER_ID)) + .contentType(MediaType.APPLICATION_JSON) + .body(Mono.just(changePasswordForm(USER_PASSWORD)), ChangePasswordForm.class) + .exchange() + .expectStatus().isForbidden() + .expectHeader().doesNotExist(LecUtils.TOKEN_RESPONSE_HEADER_NAME); + + // Ensure password didn't change + testUtils.login(UNVERIFIED_USER_EMAIL, USER_PASSWORD); + } + + + /** + * A bad admin user should not be able to change others' password. + */ + @Test + public void testBadAdminChangePasswordAnotherUser() throws Exception { + + CLIENT.post().uri(BASE_URI + "/users/{id}/password", UNVERIFIED_USER_ID) + .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, TOKENS.get(UNVERIFIED_ADMIN_ID)) + .contentType(MediaType.APPLICATION_JSON) + .body(Mono.just(changePasswordForm(ADMIN_PASSWORD)), ChangePasswordForm.class) + .exchange() + .expectStatus().isForbidden() + .expectHeader().doesNotExist(LecUtils.TOKEN_RESPONSE_HEADER_NAME); + + // Ensure password didn't change + testUtils.login(UNVERIFIED_USER_EMAIL, USER_PASSWORD); + } + + + @Test + public void testChangePasswordInvalidData() throws Exception { + + //@formatter:off + CLIENT.post().uri(BASE_URI + "/users/{id}/password", UNVERIFIED_USER_ID) + .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, TOKENS.get(ADMIN_ID)) + .contentType(MediaType.APPLICATION_JSON) + .body(Mono.just(new ChangePasswordForm()), ChangePasswordForm.class) + .exchange() + .expectStatus().isEqualTo(HttpStatus.UNPROCESSABLE_ENTITY) + .expectHeader().doesNotExist(LecUtils.TOKEN_RESPONSE_HEADER_NAME) + .expectBody(ErrorResponse.class) + .consumeWith(errorResponseResult -> { + assertErrors(errorResponseResult, + "changePasswordFormMono.oldPassword", + "changePasswordFormMono.retypePassword", + "changePasswordFormMono.password"); + }); + //@formatter:on + + // Ensure password didn't change + testUtils.login(UNVERIFIED_USER_EMAIL, USER_PASSWORD); + + // All fields too short + ChangePasswordForm form = new ChangePasswordForm(); + form.setOldPassword("short"); + form.setPassword("short"); + form.setRetypePassword("short"); + + //@formatter:off + CLIENT.post().uri(BASE_URI + "/users/{id}/password", UNVERIFIED_USER_ID) + .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, TOKENS.get(ADMIN_ID)) + .contentType(MediaType.APPLICATION_JSON) + .body(Mono.just(form), ChangePasswordForm.class) + .exchange() + .expectStatus().isEqualTo(HttpStatus.UNPROCESSABLE_ENTITY) + .expectHeader().doesNotExist(LecUtils.TOKEN_RESPONSE_HEADER_NAME) + .expectBody(ErrorResponse.class) + .consumeWith(errorResponseResult -> { + assertErrors(errorResponseResult, + "changePasswordFormMono.oldPassword", + "changePasswordFormMono.retypePassword", + "changePasswordFormMono.password"); + }); + //@formatter:on + + // Ensure password didn't change + testUtils.login(UNVERIFIED_USER_EMAIL, USER_PASSWORD); + + // different retype-password + form = changePasswordForm(USER_PASSWORD); + form.setRetypePassword("different-retype-password"); + + //@formatter:off + CLIENT.post().uri(BASE_URI + "/users/{id}/password", UNVERIFIED_USER_ID) + .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, TOKENS.get(ADMIN_ID)) + .contentType(MediaType.APPLICATION_JSON) + .body(Mono.just(form), ChangePasswordForm.class) + .exchange() + .expectStatus().isEqualTo(HttpStatus.UNPROCESSABLE_ENTITY) + .expectHeader().doesNotExist(LecUtils.TOKEN_RESPONSE_HEADER_NAME) + .expectBody(ErrorResponse.class) + .consumeWith(errorResponseResult -> { + assertErrors(errorResponseResult, + "changePasswordFormMono.retypePassword", + "changePasswordFormMono.password"); + }); + //@formatter:on + + // Ensure password didn't change + testUtils.login(UNVERIFIED_USER_EMAIL, USER_PASSWORD); + } +} diff --git a/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/LemonFieldError.java b/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/LemonFieldError.java index f32c7481..803610aa 100644 --- a/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/LemonFieldError.java +++ b/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/LemonFieldError.java @@ -12,11 +12,16 @@ import org.springframework.validation.ObjectError; import org.springframework.web.bind.support.WebExchangeBindException; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + /** * Holds a field or form error * * @author Sanjay Patel */ +@Getter @NoArgsConstructor @AllArgsConstructor public class LemonFieldError { // Name of the field. Null in case of a form level error. @@ -28,25 +33,6 @@ public class LemonFieldError { // Error message private String message; - - public LemonFieldError(String field, String code, String message) { - this.field = field; - this.code = code; - this.message = message; - } - - public String getField() { - return field; - } - - public String getCode() { - return code; - } - - public String getMessage() { - return message; - } - @Override public String toString() { return "FieldError {field=" + field + ", code=" + code + ", message=" + message + "}"; From 31948deb3a9081ef69f0b3343e2a1bf0b923e8b6 Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Sun, 22 Jul 2018 10:13:06 +0530 Subject: [PATCH 014/116] Refactored getting current user --- .../spring/lemon/commons/util/LecUtils.java | 15 +++++++++++++++ .../spring/lemon/util/LemonUtils.java | 7 +------ .../spring/lemonreactive/util/LerUtils.java | 1 - 3 files changed, 16 insertions(+), 7 deletions(-) diff --git a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/util/LecUtils.java b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/util/LecUtils.java index 0d315a1f..64a4da6e 100644 --- a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/util/LecUtils.java +++ b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/util/LecUtils.java @@ -10,6 +10,7 @@ import org.springframework.security.access.AccessDeniedException; import org.springframework.security.authentication.BadCredentialsException; import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContext; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.TreeNode; @@ -46,6 +47,20 @@ public LecUtils(ObjectMapper objectMapper) { LecUtils.objectMapper = objectMapper; log.info("Created"); } + + + /** + * Extracts the current-user from authentication object + * + * @param auth + * @return + */ + public static UserDto currentUser(SecurityContext context) { + + return currentUser(context.getAuthentication()); + } + + /** * Extracts the current-user from authentication object * diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/util/LemonUtils.java b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/util/LemonUtils.java index 18b23c5c..f0a60309 100644 --- a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/util/LemonUtils.java +++ b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/util/LemonUtils.java @@ -76,12 +76,7 @@ public static T getBean(Class clazz) { */ public static UserDto currentUser() { - // get the authentication object - Authentication auth = SecurityContextHolder - .getContext().getAuthentication(); - - // get the user from the authentication object - return LecUtils.currentUser(auth); + return LecUtils.currentUser(SecurityContextHolder.getContext()); } diff --git a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/util/LerUtils.java b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/util/LerUtils.java index ba537b54..b59fec39 100644 --- a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/util/LerUtils.java +++ b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/util/LerUtils.java @@ -45,7 +45,6 @@ public void postConstruct() { public static Mono>> currentUser() { return ReactiveSecurityContextHolder.getContext() - .map(SecurityContext::getAuthentication) .map(LecUtils::currentUser) .map(user -> Optional.of((UserDto) user)) .defaultIfEmpty(Optional.empty()); From 89711f16e7ee66336032778bbb6d43a346f99a36 Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Sun, 22 Jul 2018 13:23:43 +0530 Subject: [PATCH 015/116] Coded reactive FetchNewTokenTests --- lemon-demo-reactive/pom.xml | 6 ++ .../main/resources/config/application-dev.yml | 1 + .../spring/lemondemo/AbstractTests.java | 8 +- .../spring/lemondemo/BasicTests.java | 6 +- .../spring/lemondemo/ChangePasswordTests.java | 8 +- .../spring/lemondemo/FetchNewTokenTests.java | 101 ++++++++++++++++++ .../spring/lemondemo/LoginTests.java | 1 + .../spring/lemondemo/MyTestUtils.java | 24 ++++- .../lemondemo/dto/TestErrorResponse.java | 22 ++++ .../lemondemo/dto/TestLemonFieldError.java | 14 +++ .../spring/lemondemo/dto/TestToken.java | 9 ++ .../lemondemo/{ => dto}/TestUserDto.java | 2 +- .../lemon/exceptions/ErrorResponse.java | 35 +----- .../lemon/exceptions/LemonFieldError.java | 9 +- .../LemonReactiveAutoConfiguration.java | 2 + .../lemonreactive/LemonReactiveService.java | 2 +- .../spring/lemonreactive/util/LerUtils.java | 1 - 17 files changed, 196 insertions(+), 55 deletions(-) create mode 100644 lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/FetchNewTokenTests.java create mode 100644 lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/dto/TestErrorResponse.java create mode 100644 lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/dto/TestLemonFieldError.java create mode 100644 lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/dto/TestToken.java rename lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/{ => dto}/TestUserDto.java (87%) diff --git a/lemon-demo-reactive/pom.xml b/lemon-demo-reactive/pom.xml index d6356b2e..adc3c87b 100644 --- a/lemon-demo-reactive/pom.xml +++ b/lemon-demo-reactive/pom.xml @@ -24,6 +24,12 @@ ${project.version} + + io.projectreactor + reactor-test + test + + diff --git a/lemon-demo-reactive/src/main/resources/config/application-dev.yml b/lemon-demo-reactive/src/main/resources/config/application-dev.yml index 2cd5ec47..db1cf09b 100644 --- a/lemon-demo-reactive/src/main/resources/config/application-dev.yml +++ b/lemon-demo-reactive/src/main/resources/config/application-dev.yml @@ -4,6 +4,7 @@ spring: data: mongodb: database: lemon + security: oauth2: client: diff --git a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/AbstractTests.java b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/AbstractTests.java index 12d6110f..d9886d72 100644 --- a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/AbstractTests.java +++ b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/AbstractTests.java @@ -16,6 +16,8 @@ import com.naturalprogrammer.spring.lemon.exceptions.ErrorResponse; import com.naturalprogrammer.spring.lemon.exceptions.LemonFieldError; +import com.naturalprogrammer.spring.lemondemo.dto.TestErrorResponse; +import com.naturalprogrammer.spring.lemondemo.dto.TestLemonFieldError; @RunWith(SpringRunner.class) @SpringBootTest({ @@ -39,13 +41,13 @@ public void initialize() { } - protected void assertErrors(EntityExchangeResult errorResponseResult, String... fields) { + protected void assertErrors(EntityExchangeResult errorResponseResult, String... fields) { - ErrorResponse response = errorResponseResult.getResponseBody(); + TestErrorResponse response = errorResponseResult.getResponseBody(); assertEquals(fields.length, response.getErrors().size()); assertTrue(response.getErrors().stream() - .map(LemonFieldError::getField).collect(Collectors.toSet()) + .map(TestLemonFieldError::getField).collect(Collectors.toSet()) .containsAll(Arrays.asList(fields))); } } diff --git a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/BasicTests.java b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/BasicTests.java index dae685e1..e4b93a24 100644 --- a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/BasicTests.java +++ b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/BasicTests.java @@ -24,11 +24,7 @@ public void testPing() throws Exception { @Test public void testGetContextLoggedIn() throws Exception { - CLIENT.get() - .uri(BASE_URI + "/context") - .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, TOKENS.get(ADMIN_ID)) - .exchange() - .expectStatus().isOk() + testUtils.contextResponse(TOKENS.get(ADMIN_ID)) .expectHeader().exists(LecUtils.TOKEN_RESPONSE_HEADER_NAME) .expectBody() .jsonPath("$.context.reCaptchaSiteKey").exists() diff --git a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/ChangePasswordTests.java b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/ChangePasswordTests.java index 8b31ba4e..3e74750b 100644 --- a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/ChangePasswordTests.java +++ b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/ChangePasswordTests.java @@ -18,7 +18,7 @@ import com.naturalprogrammer.spring.lemon.commons.domain.ChangePasswordForm; import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; -import com.naturalprogrammer.spring.lemon.exceptions.ErrorResponse; +import com.naturalprogrammer.spring.lemondemo.dto.TestErrorResponse; import reactor.core.publisher.Mono; @@ -137,7 +137,7 @@ public void testChangePasswordInvalidData() throws Exception { .exchange() .expectStatus().isEqualTo(HttpStatus.UNPROCESSABLE_ENTITY) .expectHeader().doesNotExist(LecUtils.TOKEN_RESPONSE_HEADER_NAME) - .expectBody(ErrorResponse.class) + .expectBody(TestErrorResponse.class) .consumeWith(errorResponseResult -> { assertErrors(errorResponseResult, "changePasswordFormMono.oldPassword", @@ -163,7 +163,7 @@ public void testChangePasswordInvalidData() throws Exception { .exchange() .expectStatus().isEqualTo(HttpStatus.UNPROCESSABLE_ENTITY) .expectHeader().doesNotExist(LecUtils.TOKEN_RESPONSE_HEADER_NAME) - .expectBody(ErrorResponse.class) + .expectBody(TestErrorResponse.class) .consumeWith(errorResponseResult -> { assertErrors(errorResponseResult, "changePasswordFormMono.oldPassword", @@ -187,7 +187,7 @@ public void testChangePasswordInvalidData() throws Exception { .exchange() .expectStatus().isEqualTo(HttpStatus.UNPROCESSABLE_ENTITY) .expectHeader().doesNotExist(LecUtils.TOKEN_RESPONSE_HEADER_NAME) - .expectBody(ErrorResponse.class) + .expectBody(TestErrorResponse.class) .consumeWith(errorResponseResult -> { assertErrors(errorResponseResult, "changePasswordFormMono.retypePassword", diff --git a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/FetchNewTokenTests.java b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/FetchNewTokenTests.java new file mode 100644 index 00000000..426f2553 --- /dev/null +++ b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/FetchNewTokenTests.java @@ -0,0 +1,101 @@ +package com.naturalprogrammer.spring.lemondemo; + +import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.ADMIN_EMAIL; +import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.ADMIN_ID; +import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.CLIENT; +import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.TOKENS; +import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.UNVERIFIED_USER_EMAIL; +import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.UNVERIFIED_USER_ID; +import static com.naturalprogrammer.spring.lemondemo.controllers.MyController.BASE_URI; +import static org.junit.Assert.assertNotNull; +import static org.springframework.web.reactive.function.BodyInserters.fromFormData; + +import org.junit.Test; +import org.springframework.http.MediaType; +import org.springframework.test.web.reactive.server.EntityExchangeResult; + +import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; +import com.naturalprogrammer.spring.lemondemo.dto.TestToken; + +public class FetchNewTokenTests extends AbstractTests { + + + @Test + public void testFetchNewToken() throws Exception { + + CLIENT.post().uri(BASE_URI + "/fetch-new-auth-token") + .contentType(MediaType.APPLICATION_FORM_URLENCODED) + .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, TOKENS.get(UNVERIFIED_USER_ID)) + .exchange() + .expectStatus().isOk() + .expectBody(TestToken.class) + .consumeWith(this::ensureTokenWorks); + } + + + @Test + public void testFetchNewTokenExpiration() throws Exception { + + CLIENT.post().uri(BASE_URI + "/fetch-new-auth-token") + .contentType(MediaType.APPLICATION_FORM_URLENCODED) + .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, TOKENS.get(UNVERIFIED_USER_ID)) + .body(fromFormData("expirationMillis", "1000")) + .exchange() + .expectStatus().isOk() + .expectBody(TestToken.class) + .consumeWith(result -> { + + ensureTokenWorks(result); + TestToken token = result.getResponseBody(); + + try { + Thread.sleep(1001L); + } catch (InterruptedException e) { + e.printStackTrace(); + } + + CLIENT.get() + .uri(BASE_URI + "/context") + .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, token.getToken()) + .exchange() + .expectStatus().isUnauthorized(); + }); + } + + @Test + public void testFetchNewTokenByAdminForAnotherUser() throws Exception { + + CLIENT.post().uri(BASE_URI + "/fetch-new-auth-token") + .contentType(MediaType.APPLICATION_FORM_URLENCODED) + .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, TOKENS.get(ADMIN_ID)) + .body(fromFormData("username", UNVERIFIED_USER_EMAIL)) + .exchange() + .expectStatus().isOk() + .expectBody(TestToken.class) + .consumeWith(this::ensureTokenWorks); + } + + + @Test + public void testFetchNewTokenByNonAdminForAnotherUser() throws Exception { + + CLIENT.post().uri(BASE_URI + "/fetch-new-auth-token") + .contentType(MediaType.APPLICATION_FORM_URLENCODED) + .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, TOKENS.get(UNVERIFIED_USER_ID)) + .body(fromFormData("username", ADMIN_EMAIL)) + .exchange() + .expectStatus().isForbidden() + .expectBody().jsonPath("$.token").doesNotExist(); + } + + + private void ensureTokenWorks(EntityExchangeResult result) { + + TestToken token = result.getResponseBody(); + assertNotNull(token.getToken()); + + testUtils.contextResponse(token.getToken()) + .expectBody() + .jsonPath("$.user.id").isEqualTo(UNVERIFIED_USER_ID.toString()); + } +} diff --git a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/LoginTests.java b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/LoginTests.java index 82e2ac22..4472a153 100644 --- a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/LoginTests.java +++ b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/LoginTests.java @@ -16,6 +16,7 @@ import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; import com.naturalprogrammer.spring.lemondemo.domain.User; +import com.naturalprogrammer.spring.lemondemo.dto.TestUserDto; public class LoginTests extends AbstractTests { diff --git a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/MyTestUtils.java b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/MyTestUtils.java index 30169ab3..301d8f91 100644 --- a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/MyTestUtils.java +++ b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/MyTestUtils.java @@ -1,8 +1,12 @@ package com.naturalprogrammer.spring.lemondemo; +import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.ADMIN_ID; +import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.CLIENT; +import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.TOKENS; import static com.naturalprogrammer.spring.lemondemo.controllers.MyController.BASE_URI; import static org.springframework.web.reactive.function.BodyInserters.fromFormData; +import java.time.Duration; import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; @@ -21,6 +25,9 @@ import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; import com.naturalprogrammer.spring.lemondemo.domain.User; +import com.naturalprogrammer.spring.lemondemo.dto.TestUserDto; + +import reactor.test.StepVerifier; @Component public class MyTestUtils { @@ -52,7 +59,11 @@ public class MyTestUtils { private MongoTemplate mongoTemplate; public MyTestUtils(ApplicationContext context) { - CLIENT = WebTestClient.bindToApplicationContext(context).build(); + CLIENT = WebTestClient + .bindToApplicationContext(context) + .configureClient() + .responseTimeout(Duration.ofHours(1L)) + .build(); } public String login(String userName, String password) { @@ -73,7 +84,16 @@ public ResponseSpec loginResponse(String userName, String password) { .exchange(); } -// @Override + public ResponseSpec contextResponse(String token) { + + return CLIENT.get() + .uri(BASE_URI + "/context") + .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, token) + .exchange() + .expectStatus().isOk(); + } + + // @Override // public void run(String... args) throws Exception { // // TOKENS.put(ADMIN_ID, login(ADMIN_EMAIL, ADMIN_PASSWORD)); diff --git a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/dto/TestErrorResponse.java b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/dto/TestErrorResponse.java new file mode 100644 index 00000000..4cd5a417 --- /dev/null +++ b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/dto/TestErrorResponse.java @@ -0,0 +1,22 @@ +package com.naturalprogrammer.spring.lemondemo.dto; + +import java.util.Collection; + +import com.naturalprogrammer.spring.lemon.exceptions.LemonFieldError; + +import lombok.Getter; +import lombok.Setter; + +/** + * Error DTO, to be sent as response body + * in case of errors + */ +@Getter @Setter +public class TestErrorResponse { + + private String exception; + private String error; + private String message; + private Integer status; // We'd need it as integer in JSON serialization + private Collection errors; +} diff --git a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/dto/TestLemonFieldError.java b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/dto/TestLemonFieldError.java new file mode 100644 index 00000000..7ea8a782 --- /dev/null +++ b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/dto/TestLemonFieldError.java @@ -0,0 +1,14 @@ +package com.naturalprogrammer.spring.lemondemo.dto; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +@Getter @Setter @NoArgsConstructor +public class TestLemonFieldError { + + private String field; + private String code; + private String message; +} diff --git a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/dto/TestToken.java b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/dto/TestToken.java new file mode 100644 index 00000000..fced0b64 --- /dev/null +++ b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/dto/TestToken.java @@ -0,0 +1,9 @@ +package com.naturalprogrammer.spring.lemondemo.dto; + +import lombok.Getter; +import lombok.Setter; + +@Getter @Setter +public class TestToken { + private String token; +} diff --git a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/TestUserDto.java b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/dto/TestUserDto.java similarity index 87% rename from lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/TestUserDto.java rename to lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/dto/TestUserDto.java index a317f941..d5b15cc2 100644 --- a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/TestUserDto.java +++ b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/dto/TestUserDto.java @@ -1,4 +1,4 @@ -package com.naturalprogrammer.spring.lemondemo; +package com.naturalprogrammer.spring.lemondemo.dto; import java.util.HashSet; import java.util.Set; diff --git a/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/ErrorResponse.java b/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/ErrorResponse.java index bf2f2168..b591289b 100644 --- a/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/ErrorResponse.java +++ b/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/ErrorResponse.java @@ -2,10 +2,14 @@ import java.util.Collection; +import lombok.Getter; +import lombok.Setter; + /** * Error DTO, to be sent as response body * in case of errors */ +@Getter @Setter public class ErrorResponse { private String exception; @@ -18,35 +22,4 @@ public boolean incomplete() { return message == null || status == null; } - - public String getException() { - return exception; - } - public void setException(String exception) { - this.exception = exception; - } - public String getError() { - return error; - } - public void setError(String error) { - this.error = error; - } - public String getMessage() { - return message; - } - public void setMessage(String message) { - this.message = message; - } - public Integer getStatus() { - return status; - } - public void setStatus(Integer status) { - this.status = status; - } - public Collection getErrors() { - return errors; - } - public void setErrors(Collection errors) { - this.errors = errors; - } } diff --git a/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/LemonFieldError.java b/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/LemonFieldError.java index 803610aa..2a77ee5c 100644 --- a/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/LemonFieldError.java +++ b/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/LemonFieldError.java @@ -15,13 +15,14 @@ import lombok.AllArgsConstructor; import lombok.Getter; import lombok.NoArgsConstructor; +import lombok.ToString; /** * Holds a field or form error * * @author Sanjay Patel */ -@Getter @NoArgsConstructor @AllArgsConstructor +@Getter @AllArgsConstructor @ToString public class LemonFieldError { // Name of the field. Null in case of a form level error. @@ -32,12 +33,6 @@ public class LemonFieldError { // Error message private String message; - - @Override - public String toString() { - return "FieldError {field=" + field + ", code=" + code + ", message=" + message + "}"; - } - /** * Converts a set of ConstraintViolations diff --git a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveAutoConfiguration.java b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveAutoConfiguration.java index 16accf80..4730612b 100644 --- a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveAutoConfiguration.java +++ b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveAutoConfiguration.java @@ -7,6 +7,7 @@ import org.bson.types.ObjectId; import org.springframework.boot.autoconfigure.AutoConfigureBefore; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.mongo.MongoReactiveAutoConfiguration; import org.springframework.boot.autoconfigure.security.reactive.ReactiveSecurityAutoConfiguration; import org.springframework.boot.autoconfigure.security.reactive.ReactiveUserDetailsServiceAutoConfiguration; import org.springframework.boot.autoconfigure.web.reactive.WebFluxAutoConfiguration; @@ -41,6 +42,7 @@ @EnableMongoAuditing @EnableReactiveMethodSecurity @AutoConfigureBefore({ + MongoReactiveAutoConfiguration.class, WebFluxAutoConfiguration.class, ErrorWebFluxAutoConfiguration.class, // SecurityAutoConfiguration.class, diff --git a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveService.java b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveService.java index b0e1591e..e3e375d1 100644 --- a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveService.java +++ b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveService.java @@ -773,7 +773,7 @@ public Mono> fetchNewToken(ServerWebExchange exchange) { UserDto currentUser = (UserDto) tuple.getT1().get(); String username = tuple.getT2().getFirst("username"); - if (StringUtils.isNotBlank(username)) + if (StringUtils.isBlank(username)) username = currentUser.getUsername(); long expirationMillis = getExpirationMillis(tuple.getT2()); diff --git a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/util/LerUtils.java b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/util/LerUtils.java index b59fec39..b554db4e 100644 --- a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/util/LerUtils.java +++ b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/util/LerUtils.java @@ -9,7 +9,6 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.security.core.context.ReactiveSecurityContextHolder; -import org.springframework.security.core.context.SecurityContext; import com.github.fge.jsonpatch.JsonPatchException; import com.naturalprogrammer.spring.lemon.commons.security.JwtService; From 9d57f6f2a6487f20b445e89c8a468ac9139d44f2 Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Sun, 22 Jul 2018 18:27:21 +0530 Subject: [PATCH 016/116] RequestEmailChangeTests coded for WebFlux --- .../lemondemo/RequestEmailChangeMvcTests.java | 6 +- .../spring/lemondemo/AbstractTests.java | 7 +- .../spring/lemondemo/FetchUserTests.java | 116 +++++++++ .../spring/lemondemo/ForgotPasswordTests.java | 61 +++++ .../spring/lemondemo/MyTestUtils.java | 8 +- .../lemondemo/RequestEmailChangeTests.java | 229 ++++++++++++++++++ .../spring/lemondemo/dto/TestEmailForm.java | 11 + .../lemondemo/dto/TestErrorResponse.java | 2 - .../lemondemo/dto/TestLemonFieldError.java | 1 - .../lemonreactive/LemonReactiveService.java | 2 +- 10 files changed, 425 insertions(+), 18 deletions(-) create mode 100644 lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/FetchUserTests.java create mode 100644 lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/ForgotPasswordTests.java create mode 100644 lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/RequestEmailChangeTests.java create mode 100644 lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/dto/TestEmailForm.java diff --git a/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/RequestEmailChangeMvcTests.java b/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/RequestEmailChangeMvcTests.java index a403654f..14e2fff4 100644 --- a/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/RequestEmailChangeMvcTests.java +++ b/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/RequestEmailChangeMvcTests.java @@ -101,10 +101,6 @@ public void testNonAdminRequestEmailChangeAnotherUser() throws Exception { * A bad admin trying to change the email id * of another user */ - /** - * A non-admin should not be able to request changing - * the email id of another user - */ @Test public void testBadAdminRequestEmailChangeAnotherUser() throws Exception { @@ -140,7 +136,7 @@ public void tryingWithInvalidData() throws JsonProcessingException, Exception { updatedUser.setPassword(""); updatedUser.setNewEmail(""); - // try with null newEmail and password + // try with blank newEmail and password mvc.perform(post("/api/core/users/{id}/email-change-request", UNVERIFIED_USER_ID) .contentType(MediaType.APPLICATION_JSON) .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, tokens.get(UNVERIFIED_USER_ID)) diff --git a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/AbstractTests.java b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/AbstractTests.java index d9886d72..a83ee838 100644 --- a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/AbstractTests.java +++ b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/AbstractTests.java @@ -10,12 +10,12 @@ import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.data.mongodb.core.MongoTemplate; import org.springframework.test.context.junit4.SpringRunner; import org.springframework.test.web.reactive.server.EntityExchangeResult; -import com.naturalprogrammer.spring.lemon.exceptions.ErrorResponse; -import com.naturalprogrammer.spring.lemon.exceptions.LemonFieldError; +import com.naturalprogrammer.spring.lemon.commons.mail.MailSender; import com.naturalprogrammer.spring.lemondemo.dto.TestErrorResponse; import com.naturalprogrammer.spring.lemondemo.dto.TestLemonFieldError; @@ -34,6 +34,9 @@ public abstract class AbstractTests { @Autowired protected MyTestUtils testUtils; + @MockBean + protected MailSender mailSender; + @Before public void initialize() { diff --git a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/FetchUserTests.java b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/FetchUserTests.java new file mode 100644 index 00000000..98881a47 --- /dev/null +++ b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/FetchUserTests.java @@ -0,0 +1,116 @@ +package com.naturalprogrammer.spring.lemondemo; + +import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.ADMIN_EMAIL; +import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.ADMIN_ID; +import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.CLIENT; +import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.TOKENS; +import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.UNVERIFIED_USER_EMAIL; +import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.UNVERIFIED_USER_ID; +import static com.naturalprogrammer.spring.lemondemo.controllers.MyController.BASE_URI; +import static org.springframework.web.reactive.function.BodyInserters.fromFormData; + +import org.bson.types.ObjectId; +import org.junit.Test; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; + +import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; + +public class FetchUserTests extends AbstractTests { + + @Test + public void testFetchUserById() throws Exception { + + CLIENT.get().uri(BASE_URI + "/users/{id}", ADMIN_ID) + .exchange() + .expectStatus().isOk() + .expectBody() + .jsonPath("$.id").isEqualTo(ADMIN_ID.toString()) + .jsonPath("$.email").doesNotExist() + .jsonPath("$.password").doesNotExist() + .jsonPath("$.credentialsUpdatedAt").doesNotExist() + .jsonPath("$.name").isEqualTo("Admin 1"); + } + + @Test + public void testFetchUserByIdLoggedIn() throws Exception { + + // Same user logged in + CLIENT.get().uri(BASE_URI + "/users/{id}", ADMIN_ID) + .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, TOKENS.get(ADMIN_ID)) + .exchange() + .expectStatus().isOk() + .expectBody() + .jsonPath("$.id").isEqualTo(ADMIN_ID.toString()) + .jsonPath("$.email").isEqualTo(ADMIN_EMAIL) + .jsonPath("$.password").doesNotExist() + .jsonPath("$.credentialsUpdatedAt").doesNotExist() + .jsonPath("$.name").isEqualTo("Admin 1"); + + // Another user logged in + CLIENT.get().uri(BASE_URI + "/users/{id}", ADMIN_ID) + .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, TOKENS.get(UNVERIFIED_USER_ID)) + .exchange() + .expectStatus().isOk() + .expectBody() + .jsonPath("$.id").isEqualTo(ADMIN_ID.toString()) + .jsonPath("$.email").doesNotExist(); + + // Admin user logged in - fetching another user + CLIENT.get().uri(BASE_URI + "/users/{id}", UNVERIFIED_USER_ID) + .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, TOKENS.get(ADMIN_ID)) + .exchange() + .expectStatus().isOk() + .expectBody() + .jsonPath("$.id").isEqualTo(UNVERIFIED_USER_ID.toString()) + .jsonPath("$.email").isEqualTo(UNVERIFIED_USER_EMAIL); + } + + @Test + public void testFetchNonExistingUserById() throws Exception { + + CLIENT.get().uri(BASE_URI + "/users/{id}", ObjectId.get()) + .exchange() + .expectStatus().isNotFound(); + } + + @Test + public void testFetchUserByEmail() throws Exception { + + CLIENT.post().uri(BASE_URI + "/users/fetch-by-email") + .contentType(MediaType.APPLICATION_FORM_URLENCODED) + .body(fromFormData("email", ADMIN_EMAIL)) + .exchange() + .expectStatus().isOk() + .expectBody() + .jsonPath("$.id").isEqualTo(ADMIN_ID.toString()) + .jsonPath("$.password").doesNotExist() + .jsonPath("$.credentialsUpdatedAt").doesNotExist() + .jsonPath("$.name").isEqualTo("Admin 1"); + } + + @Test + public void testFetchUserByInvalidEmail() throws Exception { + + // email does not exist + CLIENT.post().uri(BASE_URI + "/users/fetch-by-email") + .contentType(MediaType.APPLICATION_FORM_URLENCODED) + .body(fromFormData("email", "foo@example.com")) + .exchange() + .expectStatus().isNotFound(); + + // Blank email + CLIENT.post().uri(BASE_URI + "/users/fetch-by-email") + .contentType(MediaType.APPLICATION_FORM_URLENCODED) + .body(fromFormData("email", "")) + .exchange() + .expectStatus().isEqualTo(HttpStatus.UNPROCESSABLE_ENTITY); + + // Invalid email + CLIENT.post().uri(BASE_URI + "/users/fetch-by-email") + .contentType(MediaType.APPLICATION_FORM_URLENCODED) + .body(fromFormData("email", "invalid-email")) + .exchange() + .expectStatus().isNotFound(); + } +} diff --git a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/ForgotPasswordTests.java b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/ForgotPasswordTests.java new file mode 100644 index 00000000..1658e662 --- /dev/null +++ b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/ForgotPasswordTests.java @@ -0,0 +1,61 @@ +package com.naturalprogrammer.spring.lemondemo; + +import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.ADMIN_EMAIL; +import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.CLIENT; +import static com.naturalprogrammer.spring.lemondemo.controllers.MyController.BASE_URI; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; +import static org.springframework.web.reactive.function.BodyInserters.fromFormData; + +import org.junit.Test; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; + +public class ForgotPasswordTests extends AbstractTests { + + @Test + public void testForgotPassword() { + + CLIENT.post().uri(BASE_URI + "/forgot-password") + .contentType(MediaType.APPLICATION_FORM_URLENCODED) + .body(fromFormData("email", ADMIN_EMAIL)) + .exchange() + .expectStatus().isNoContent(); + + verify(mailSender).send(any()); + } + + @Test + public void testForgotPasswordInvalidEmail() throws Exception { + + // Unknown email + CLIENT.post().uri(BASE_URI + "/forgot-password") + .contentType(MediaType.APPLICATION_FORM_URLENCODED) + .body(fromFormData("email", "unknown@example.com")) + .exchange() + .expectStatus().isNotFound(); + + // Null email + CLIENT.post().uri(BASE_URI + "/forgot-password") + .contentType(MediaType.APPLICATION_FORM_URLENCODED) + .exchange() + .expectStatus().isEqualTo(HttpStatus.UNPROCESSABLE_ENTITY); + + // Blank email + CLIENT.post().uri(BASE_URI + "/forgot-password") + .contentType(MediaType.APPLICATION_FORM_URLENCODED) + .body(fromFormData("email", "")) + .exchange() + .expectStatus().isEqualTo(HttpStatus.UNPROCESSABLE_ENTITY); + + // Wrong email format + CLIENT.post().uri(BASE_URI + "/forgot-password") + .contentType(MediaType.APPLICATION_FORM_URLENCODED) + .body(fromFormData("email", "wrong-email-format")) + .exchange() + .expectStatus().isNotFound(); + + verify(mailSender, never()).send(any()); + } +} diff --git a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/MyTestUtils.java b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/MyTestUtils.java index 301d8f91..781b8fd3 100644 --- a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/MyTestUtils.java +++ b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/MyTestUtils.java @@ -1,8 +1,5 @@ package com.naturalprogrammer.spring.lemondemo; -import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.ADMIN_ID; -import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.CLIENT; -import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.TOKENS; import static com.naturalprogrammer.spring.lemondemo.controllers.MyController.BASE_URI; import static org.springframework.web.reactive.function.BodyInserters.fromFormData; @@ -27,8 +24,6 @@ import com.naturalprogrammer.spring.lemondemo.domain.User; import com.naturalprogrammer.spring.lemondemo.dto.TestUserDto; -import reactor.test.StepVerifier; - @Component public class MyTestUtils { @@ -57,7 +52,7 @@ public class MyTestUtils { @Autowired private MongoTemplate mongoTemplate; - + public MyTestUtils(ApplicationContext context) { CLIENT = WebTestClient .bindToApplicationContext(context) @@ -119,7 +114,6 @@ public void initDatabase() { log.debug("Created users."); } - private void createUser(ObjectId id, String email, String password, String name, String... roles) { User user = new User(); diff --git a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/RequestEmailChangeTests.java b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/RequestEmailChangeTests.java new file mode 100644 index 00000000..63277e8e --- /dev/null +++ b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/RequestEmailChangeTests.java @@ -0,0 +1,229 @@ +package com.naturalprogrammer.spring.lemondemo; + +import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.ADMIN_EMAIL; +import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.ADMIN_ID; +import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.CLIENT; +import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.TOKENS; +import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.UNVERIFIED_ADMIN_ID; +import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.UNVERIFIED_USER_EMAIL; +import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.UNVERIFIED_USER_ID; +import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.USER_ID; +import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.USER_PASSWORD; +import static com.naturalprogrammer.spring.lemondemo.controllers.MyController.BASE_URI; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; + +import org.bson.types.ObjectId; +import org.junit.Assert; +import org.junit.Test; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.test.web.reactive.server.WebTestClient.BodySpec; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; +import com.naturalprogrammer.spring.lemondemo.domain.User; +import com.naturalprogrammer.spring.lemondemo.dto.TestEmailForm; +import com.naturalprogrammer.spring.lemondemo.dto.TestErrorResponse; + +import reactor.core.publisher.Mono; + +public class RequestEmailChangeTests extends AbstractTests { + + private static final String NEW_EMAIL = "new.email@example.com"; + + private TestEmailForm form() { + + TestEmailForm emailForm = new TestEmailForm(); + emailForm.setPassword(USER_PASSWORD); + emailForm.setNewEmail(NEW_EMAIL); + + return emailForm; + } + + + @Test + public void testRequestEmailChange() { + + CLIENT.post().uri(BASE_URI + "/users/{id}/email-change-request", UNVERIFIED_USER_ID) + .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, TOKENS.get(UNVERIFIED_USER_ID)) + .contentType(MediaType.APPLICATION_JSON) + .body(Mono.just(form()), TestEmailForm.class) + .exchange() + .expectStatus().isNoContent(); + + verify(mailSender).send(any()); + + User updatedUser = mongoTemplate.findById(UNVERIFIED_USER_ID, User.class); + Assert.assertEquals(NEW_EMAIL, updatedUser.getNewEmail()); + Assert.assertEquals(UNVERIFIED_USER_EMAIL, updatedUser.getEmail()); + } + + + /** + * A good admin should be able to request changing email of another user. + */ + @Test + public void testGoodAdminRequestEmailChange() throws Exception { + + CLIENT.post().uri(BASE_URI + "/users/{id}/email-change-request", UNVERIFIED_USER_ID) + .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, TOKENS.get(ADMIN_ID)) + .contentType(MediaType.APPLICATION_JSON) + .body(Mono.just(form()), TestEmailForm.class) + .exchange() + .expectStatus().isNoContent(); + + User updatedUser = mongoTemplate.findById(UNVERIFIED_USER_ID, User.class); + Assert.assertEquals(NEW_EMAIL, updatedUser.getNewEmail()); + } + + + /** + * A request changing email of unknown user. + */ + @Test + public void testRequestEmailChangeUnknownUser() throws Exception { + + CLIENT.post().uri(BASE_URI + "/users/{id}/email-change-request", ObjectId.get()) + .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, TOKENS.get(ADMIN_ID)) + .contentType(MediaType.APPLICATION_JSON) + .body(Mono.just(form()), TestEmailForm.class) + .exchange() + .expectStatus().isNotFound(); + + verify(mailSender, never()).send(any()); + } + + + /** + * A non-admin should not be able to request changing + * the email id of another user + */ + @Test + public void testNonAdminRequestEmailChangeAnotherUser() throws Exception { + + CLIENT.post().uri(BASE_URI + "/users/{id}/email-change-request", ADMIN_ID) + .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, TOKENS.get(USER_ID)) + .contentType(MediaType.APPLICATION_JSON) + .body(Mono.just(form()), TestEmailForm.class) + .exchange() + .expectStatus().isForbidden(); + + assertNotChanged(); + verify(mailSender, never()).send(any()); + } + + + /** + * A bad admin trying to change the email id + * of another user + */ + @Test + public void testBadAdminRequestEmailChangeAnotherUser() throws Exception { + + CLIENT.post().uri(BASE_URI + "/users/{id}/email-change-request", ADMIN_ID) + .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, TOKENS.get(UNVERIFIED_ADMIN_ID)) + .contentType(MediaType.APPLICATION_JSON) + .body(Mono.just(form()), TestEmailForm.class) + .exchange() + .expectStatus().isForbidden(); + + assertNotChanged(); + verify(mailSender, never()).send(any()); + } + + + /** + * Trying with invalid data. + * @throws Exception + * @throws JsonProcessingException + */ + @Test + public void testRequestEmailChangeWithInvalidData() { + + // try with null newEmail and password + tryRequestingEmailChangeBodySpec(new TestEmailForm()) + .consumeWith(errorResponseResult -> { + assertErrors(errorResponseResult, + "emailFormMono.newEmail", + "emailFormMono.password"); + }); + assertNotChanged(); + + // try with blank newEmail and password + TestEmailForm emailForm = new TestEmailForm(); + emailForm.setPassword(""); + emailForm.setNewEmail(""); + tryRequestingEmailChangeBodySpec(emailForm) + .consumeWith(errorResponseResult -> { + assertErrors(errorResponseResult, + "emailFormMono.newEmail", + "emailFormMono.newEmail", + "emailFormMono.password", + "emailFormMono.password"); + }); + + // try with invalid newEmail + emailForm = form(); + emailForm.setNewEmail("an-invalid-email"); + tryRequestingEmailChangeBodySpec(emailForm) + .consumeWith(errorResponseResult -> { + assertErrors(errorResponseResult, + "emailFormMono.newEmail"); + }); + assertNotChanged(); + + // try with wrong password + emailForm = form(); + emailForm.setPassword("wrong-password"); + tryRequestingEmailChangeBodySpec(emailForm) + .consumeWith(errorResponseResult -> { + assertErrors(errorResponseResult, + "emailFormMono.password"); + }); + assertNotChanged(); + + // try with null password + emailForm = form(); + emailForm.setPassword(null); + tryRequestingEmailChangeBodySpec(emailForm) + .consumeWith(errorResponseResult -> { + assertErrors(errorResponseResult, + "emailFormMono.password"); + }); + assertNotChanged(); + + // try with an existing email + emailForm = form(); + emailForm.setNewEmail(ADMIN_EMAIL);; + tryRequestingEmailChangeBodySpec(emailForm) + .consumeWith(errorResponseResult -> { + assertErrors(errorResponseResult, + "emailFormMono.newEmail"); + }); + assertNotChanged(); + + verify(mailSender, never()).send(any()); + } + + + private BodySpec tryRequestingEmailChangeBodySpec(TestEmailForm form) { + + //@formatter:off + return CLIENT.post().uri(BASE_URI + "/users/{id}/email-change-request", UNVERIFIED_USER_ID) + .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, TOKENS.get(UNVERIFIED_USER_ID)) + .contentType(MediaType.APPLICATION_JSON) + .body(Mono.just(form), TestEmailForm.class) + .exchange() + .expectStatus().isEqualTo(HttpStatus.UNPROCESSABLE_ENTITY) + .expectBody(TestErrorResponse.class); + //@formatter:on + } + + + private void assertNotChanged() { + User updatedUser = mongoTemplate.findById(UNVERIFIED_USER_ID, User.class); + Assert.assertNull(updatedUser.getNewEmail()); + } +} diff --git a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/dto/TestEmailForm.java b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/dto/TestEmailForm.java new file mode 100644 index 00000000..3cdd8297 --- /dev/null +++ b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/dto/TestEmailForm.java @@ -0,0 +1,11 @@ +package com.naturalprogrammer.spring.lemondemo.dto; + +import lombok.Getter; +import lombok.Setter; + +@Getter @Setter +public class TestEmailForm { + + private String newEmail; + private String password; +} diff --git a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/dto/TestErrorResponse.java b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/dto/TestErrorResponse.java index 4cd5a417..9c4d9891 100644 --- a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/dto/TestErrorResponse.java +++ b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/dto/TestErrorResponse.java @@ -2,8 +2,6 @@ import java.util.Collection; -import com.naturalprogrammer.spring.lemon.exceptions.LemonFieldError; - import lombok.Getter; import lombok.Setter; diff --git a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/dto/TestLemonFieldError.java b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/dto/TestLemonFieldError.java index 7ea8a782..2aa8da3d 100644 --- a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/dto/TestLemonFieldError.java +++ b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/dto/TestLemonFieldError.java @@ -1,6 +1,5 @@ package com.naturalprogrammer.spring.lemondemo.dto; -import lombok.AllArgsConstructor; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; diff --git a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveService.java b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveService.java index e3e375d1..0b01efed 100644 --- a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveService.java +++ b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveService.java @@ -637,7 +637,7 @@ protected void requestEmailChange(Tuple3 tuple) { log.debug("Requesting email change: " + user); // checks - LexUtils.validate("updatedUser.password", + LexUtils.validate("emailFormMono.password", passwordEncoder.matches(emailForm.getPassword(), user.getPassword()), "com.naturalprogrammer.spring.wrong.password").go(); From b64208f81aedc0c497e80fe0c65c4b1b3189b5fc Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Sun, 22 Jul 2018 21:47:33 +0530 Subject: [PATCH 017/116] Coded reactive SignupTests --- .../spring/lemondemo/SignupMvcTests.java | 14 --- .../ResendVerificationMailTests.java | 103 ++++++++++++++++++ .../spring/lemondemo/ResetPasswordTests.java | 86 +++++++++++++++ .../spring/lemondemo/SignupTests.java | 100 +++++++++++++++++ .../lemondemo/dto/TestResetPasswordForm.java | 15 +++ .../spring/lemondemo/dto/TestUser.java | 11 ++ .../lemonreactive/LemonReactiveService.java | 5 +- .../domain/AbstractMongoUser.java | 8 +- 8 files changed, 325 insertions(+), 17 deletions(-) create mode 100644 lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/ResendVerificationMailTests.java create mode 100644 lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/ResetPasswordTests.java create mode 100644 lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/SignupTests.java create mode 100644 lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/dto/TestResetPasswordForm.java create mode 100644 lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/dto/TestUser.java diff --git a/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/SignupMvcTests.java b/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/SignupMvcTests.java index f6ef38d8..5282f0be 100644 --- a/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/SignupMvcTests.java +++ b/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/SignupMvcTests.java @@ -67,20 +67,6 @@ public void testSignup() throws Exception { Assert.assertNotEquals("user123", userRepository.findByEmail("user.foo@example.com").get().getPassword()); } -// @Test -// public void testSignupLoggedIn() throws Exception { -// -// String adminToken = login("admin@example.com", "admin!"); -// -// User user = new User("user1@example.com", "user123", "User 1"); -// -// mvc.perform(post("/api/core/users") -// .header(LemonSecurityConfig.TOKEN_REQUEST_HEADER_NAME, adminToken) -// .contentType(MediaType.APPLICATION_JSON) -// .content(LemonUtils.toJson(user))) -// .andExpect(status().is(403)); -// } -// @Test public void testSignupDuplicateEmail() throws Exception { diff --git a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/ResendVerificationMailTests.java b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/ResendVerificationMailTests.java new file mode 100644 index 00000000..126d4692 --- /dev/null +++ b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/ResendVerificationMailTests.java @@ -0,0 +1,103 @@ +package com.naturalprogrammer.spring.lemondemo; + +import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.ADMIN_ID; +import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.BLOCKED_ADMIN_ID; +import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.CLIENT; +import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.TOKENS; +import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.UNVERIFIED_ADMIN_ID; +import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.UNVERIFIED_USER_ID; +import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.USER_ID; +import static com.naturalprogrammer.spring.lemondemo.controllers.MyController.BASE_URI; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; + +import org.bson.types.ObjectId; +import org.junit.Test; +import org.springframework.http.HttpStatus; +import org.springframework.test.web.reactive.server.WebTestClient.ResponseSpec; + +import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; + +public class ResendVerificationMailTests extends AbstractTests { + + @Test + public void testResendVerificationMail() { + + resendVerificationMail(UNVERIFIED_USER_ID, UNVERIFIED_USER_ID) + .expectStatus().isNoContent(); + + verify(mailSender).send(any()); + } + + + @Test + public void testAdminResendVerificationMailOtherUser() { + + resendVerificationMail(UNVERIFIED_USER_ID, ADMIN_ID) + .expectStatus().isNoContent(); + } + + + @Test + public void testBadAdminResendVerificationMailOtherUser() { + + resendVerificationMail(UNVERIFIED_USER_ID, UNVERIFIED_ADMIN_ID) + .expectStatus().isForbidden(); + + resendVerificationMail(UNVERIFIED_USER_ID, BLOCKED_ADMIN_ID) + .expectStatus().isForbidden(); + + verify(mailSender, never()).send(any()); + } + + + @Test + public void testResendVerificationMailUnauthenticated() { + + CLIENT.post().uri(BASE_URI + "/users/{id}/resend-verification-mail", UNVERIFIED_USER_ID) + .exchange() + .expectStatus().isForbidden(); + + verify(mailSender, never()).send(any()); + } + + + @Test + public void testResendVerificationMailAlreadyVerified() { + + resendVerificationMail(USER_ID, USER_ID) + .expectStatus().isEqualTo(HttpStatus.UNPROCESSABLE_ENTITY); + + verify(mailSender, never()).send(any()); + } + + + @Test + public void testResendVerificationMailOtherUser() { + + resendVerificationMail(UNVERIFIED_USER_ID, USER_ID) + .expectStatus().isForbidden(); + + verify(mailSender, never()).send(any()); + } + + + @Test + public void testResendVerificationMailNonExistingUser() { + + resendVerificationMail(ObjectId.get(), ADMIN_ID) + .expectStatus().isNotFound(); + + verify(mailSender, never()).send(any()); + } + + + private ResponseSpec resendVerificationMail(ObjectId userId, ObjectId loggedInId) { + + return CLIENT.post().uri(BASE_URI + "/users/{id}/resend-verification-mail", userId) + .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, TOKENS.get(loggedInId)) + .exchange(); + + } +} diff --git a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/ResetPasswordTests.java b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/ResetPasswordTests.java new file mode 100644 index 00000000..6782758a --- /dev/null +++ b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/ResetPasswordTests.java @@ -0,0 +1,86 @@ +package com.naturalprogrammer.spring.lemondemo; + +import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.ADMIN_EMAIL; +import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.ADMIN_ID; +import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.CLIENT; +import static com.naturalprogrammer.spring.lemondemo.controllers.MyController.BASE_URI; + +import org.junit.Before; +import org.junit.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.test.web.reactive.server.WebTestClient.ResponseSpec; + +import com.naturalprogrammer.spring.lemon.commons.security.JwtService; +import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; +import com.naturalprogrammer.spring.lemondemo.dto.TestResetPasswordForm; + +import reactor.core.publisher.Mono; + +public class ResetPasswordTests extends AbstractTests { + + private String forgotPasswordCode; + + @Autowired + private JwtService jwtService; + + @Before + public void setUp() { + + forgotPasswordCode = jwtService.createToken( + JwtService.FORGOT_PASSWORD_AUDIENCE, + ADMIN_EMAIL, 60000L); + } + + @Test + public void testResetPassword() throws Exception { + + final String NEW_PASSWORD = "newPassword!"; + + resetPassword(forgotPasswordCode, NEW_PASSWORD) + .expectStatus().isOk() + .expectHeader().exists(LecUtils.TOKEN_RESPONSE_HEADER_NAME) + .expectBody().jsonPath("$.id").isEqualTo(ADMIN_ID.toString()); + + // Ensure able to login with new password + testUtils.login(ADMIN_EMAIL, NEW_PASSWORD); + + // Repeating shouldn't work + resetPassword(forgotPasswordCode, NEW_PASSWORD) + .expectStatus().isUnauthorized(); + } + + @Test + public void testResetPasswordInvalidData() throws Exception { + + // Wrong code + resetPassword("wrong-code", "abc99!") + .expectStatus().isUnauthorized(); + + // Blank password + resetPassword(forgotPasswordCode, "") + .expectStatus().isEqualTo(HttpStatus.UNPROCESSABLE_ENTITY); + + // Invalid password + resetPassword(forgotPasswordCode, "abc") + .expectStatus().isEqualTo(HttpStatus.UNPROCESSABLE_ENTITY); + } + + private ResponseSpec resetPassword(String forgotPasswordCode, String newPassword) { + + return CLIENT.post().uri(BASE_URI + "/reset-password") + .contentType(MediaType.APPLICATION_JSON) + .body(Mono.just(form(forgotPasswordCode, newPassword)), TestResetPasswordForm.class) + .exchange(); + } + + private TestResetPasswordForm form(String code, String newPassword) { + + TestResetPasswordForm form = new TestResetPasswordForm(); + form.setCode(code); + form.setNewPassword(newPassword); + + return form; + } +} diff --git a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/SignupTests.java b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/SignupTests.java new file mode 100644 index 00000000..9b333801 --- /dev/null +++ b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/SignupTests.java @@ -0,0 +1,100 @@ +package com.naturalprogrammer.spring.lemondemo; + +import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.ADMIN_EMAIL; +import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.CLIENT; +import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.UNVERIFIED_USER_ID; +import static com.naturalprogrammer.spring.lemondemo.controllers.MyController.BASE_URI; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; +import static org.springframework.data.mongodb.core.query.Criteria.where; +import static org.springframework.data.mongodb.core.query.Query.query; + +import org.junit.Test; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.test.web.reactive.server.WebTestClient.ResponseSpec; + +import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; +import com.naturalprogrammer.spring.lemondemo.domain.User; +import com.naturalprogrammer.spring.lemondemo.dto.TestErrorResponse; +import com.naturalprogrammer.spring.lemondemo.dto.TestUser; +import com.naturalprogrammer.spring.lemondemo.dto.TestUserDto; + +import reactor.core.publisher.Mono; + +public class SignupTests extends AbstractTests { + + @Test + public void testSignup() throws Exception { + + signup("user.foo@example.com", "user123", "User Foo") + .expectStatus().isCreated() + .expectHeader().exists(LecUtils.TOKEN_RESPONSE_HEADER_NAME) + .expectBody(TestUserDto.class) + .consumeWith(result -> { + TestUserDto userDto = result.getResponseBody(); + assertNotNull(userDto.getId()); + assertNull(userDto.getPassword()); + assertEquals("user.foo@example.com", userDto.getUsername()); + assertEquals(1, userDto.getRoles().size()); + assertTrue(userDto.getRoles().contains("UNVERIFIED")); + assertEquals("User Foo", userDto.getTag().getName()); + assertTrue(userDto.isUnverified()); + assertFalse(userDto.isBlocked()); + assertFalse(userDto.isAdmin()); + assertFalse(userDto.isGoodUser()); + assertFalse(userDto.isGoodAdmin()); + }); + + verify(mailSender).send(any()); + + // Ensure that password got encrypted + assertNotEquals("user123", + mongoTemplate.findOne(query(where("email").is("user.foo@example.com")), + User.class).getPassword()); + } + + @Test + public void testSignupWithInvalidData() throws Exception { + + signup("abc", "user1", null) + .expectStatus().isEqualTo(HttpStatus.UNPROCESSABLE_ENTITY) + .expectBody(TestErrorResponse.class) + .consumeWith(errorResponseResult -> { + assertErrors(errorResponseResult, + "userMono.email", + "userMono.email", + "userMono.password", + "userMono.name"); + }); + + verify(mailSender, never()).send(any()); + } + + @Test + public void testSignupDuplicateEmail() throws Exception { + + signup(ADMIN_EMAIL, "user123", "User Foo") + .expectStatus().isEqualTo(HttpStatus.UNPROCESSABLE_ENTITY); + + verify(mailSender, never()).send(any()); + } + + private ResponseSpec signup(String email, String password, String name) { + + TestUser user = new TestUser(email, password, name); + + return CLIENT.post().uri(BASE_URI + "/users", UNVERIFIED_USER_ID) + .contentType(MediaType.APPLICATION_JSON) + .body(Mono.just(user), TestUser.class) + .exchange(); + } + +} diff --git a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/dto/TestResetPasswordForm.java b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/dto/TestResetPasswordForm.java new file mode 100644 index 00000000..086f76ba --- /dev/null +++ b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/dto/TestResetPasswordForm.java @@ -0,0 +1,15 @@ +package com.naturalprogrammer.spring.lemondemo.dto; + +import javax.validation.constraints.NotBlank; + +import com.naturalprogrammer.spring.lemon.commons.validation.Password; + +import lombok.Getter; +import lombok.Setter; + +@Getter @Setter +public class TestResetPasswordForm { + + private String code; + private String newPassword; +} diff --git a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/dto/TestUser.java b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/dto/TestUser.java new file mode 100644 index 00000000..448b3711 --- /dev/null +++ b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/dto/TestUser.java @@ -0,0 +1,11 @@ +package com.naturalprogrammer.spring.lemondemo.dto; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.Setter; + +@Getter @Setter @AllArgsConstructor +public class TestUser { + + private String email, password, name; +} diff --git a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveService.java b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveService.java index 0b01efed..4d45d0de 100644 --- a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveService.java +++ b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveService.java @@ -197,7 +197,8 @@ public Mono> signup(Mono user) { return user .doOnNext(this::initUser) .flatMap(userRepository::insert) - .doOnSuccess(this::sendVerificationMail) + .doOnNext(this::sendVerificationMail) + .doOnNext(AbstractMongoUser::eraseCredentials) .map(AbstractMongoUser::toUserDto); } @@ -568,7 +569,7 @@ protected void hideConfidentialFields(Tuple2>> U user = tuple.getT1(); - user.setPassword(null); // JsonIgnore didn't work + user.eraseCredentials(); if (!user.hasPermission(tuple.getT2().orElse(null), UserUtils.Permission.EDIT)) user.setEmail(null); diff --git a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/domain/AbstractMongoUser.java b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/domain/AbstractMongoUser.java index 9fd5711d..8878c168 100644 --- a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/domain/AbstractMongoUser.java +++ b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/domain/AbstractMongoUser.java @@ -6,6 +6,7 @@ import org.springframework.data.annotation.Transient; import org.springframework.data.mongodb.core.index.Indexed; +import org.springframework.security.core.CredentialsContainer; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonView; @@ -20,7 +21,7 @@ @Getter @Setter public abstract class AbstractMongoUser - extends AbstractDocument { + extends AbstractDocument implements CredentialsContainer { // email @JsonView(UserUtils.SignupInput.class) @@ -107,4 +108,9 @@ protected Serializable toTag() { return null; } + + @Override + public void eraseCredentials() { + password = null; + } } From 44247fb39de8a5ea4a37c70e99950f12a0269ba3 Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Mon, 23 Jul 2018 09:45:40 +0530 Subject: [PATCH 018/116] Onto reactive UpdateUserTests --- .../LemonCommonsAutoConfiguration.java | 5 +- .../spring/lemon/commons/util/LecUtils.java | 77 ++++++++++++++++++- .../spring/lemon/LemonAutoConfiguration.java | 2 +- .../security/LemonOAuth2UserService.java | 4 +- .../spring/lemon/util/LemonUtils.java | 75 +----------------- .../LemonReactiveController.java | 3 +- 6 files changed, 82 insertions(+), 84 deletions(-) diff --git a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/LemonCommonsAutoConfiguration.java b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/LemonCommonsAutoConfiguration.java index a09563df..ed306971 100644 --- a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/LemonCommonsAutoConfiguration.java +++ b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/LemonCommonsAutoConfiguration.java @@ -5,6 +5,7 @@ import org.springframework.boot.autoconfigure.AutoConfigureBefore; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; @@ -114,7 +115,7 @@ public MailSender smtpMailSender(JavaMailSender javaMailSender) { } @Bean - public LecUtils lecUtils(ObjectMapper objectMapper) { - return new LecUtils(objectMapper); + public LecUtils lecUtils(ApplicationContext applicationContext, ObjectMapper objectMapper) { + return new LecUtils(applicationContext, objectMapper); } } diff --git a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/util/LecUtils.java b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/util/LecUtils.java index 64a4da6e..0f57054d 100644 --- a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/util/LecUtils.java +++ b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/util/LecUtils.java @@ -2,18 +2,26 @@ import java.io.IOException; import java.io.Serializable; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; import java.util.HashMap; import java.util.Map; +import java.util.Scanner; +import java.util.UUID; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.springframework.context.ApplicationContext; +import org.springframework.core.io.Resource; import org.springframework.security.access.AccessDeniedException; import org.springframework.security.authentication.BadCredentialsException; import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContext; +import com.fasterxml.jackson.core.JsonParseException; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.TreeNode; +import com.fasterxml.jackson.databind.JsonMappingException; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.github.fge.jsonpatch.JsonPatch; @@ -40,11 +48,15 @@ public class LecUtils { public static final String TOKEN_REQUEST_HEADER_NAME = "Authorization"; public static final String TOKEN_RESPONSE_HEADER_NAME = "Lemon-Authorization"; - private static ObjectMapper objectMapper; + public static ApplicationContext applicationContext; + public static ObjectMapper objectMapper; - public LecUtils(ObjectMapper objectMapper) { + public LecUtils(ApplicationContext applicationContext, + ObjectMapper objectMapper) { + + LecUtils.applicationContext = applicationContext; + LecUtils.objectMapper = objectMapper; - LecUtils.objectMapper = objectMapper; log.info("Created"); } @@ -148,5 +160,62 @@ public static T applyPatch(T originalObj, String patchString) // Convert the patched node to an updated obj return objectMapper.treeToValue(patchedObjNode, (Class) originalObj.getClass()); - } + } + + + /** + * Reads a resource into a String + */ + public static String toStr(Resource resource) throws IOException { + + String text = null; + try (Scanner scanner = new Scanner(resource.getInputStream(), StandardCharsets.UTF_8.name())) { + text = scanner.useDelimiter("\\A").next(); + } + + return text; + } + + public static ObjectMapper mapper() { + + return objectMapper; + } + + + /** + * Gets the reference to an application-context bean + * + * @param clazz the type of the bean + */ + public static T getBean(Class clazz) { + return applicationContext.getBean(clazz); + } + + + /** + * Generates a random unique string + */ + public static String uid() { + + return UUID.randomUUID().toString(); + } + + + /** + * Serializes an object to JSON string + */ + public static String toJson(T obj) throws JsonProcessingException { + + return objectMapper.writeValueAsString(obj); + } + + + /** + * Deserializes a JSON String + */ + public static T fromJson(String json, Class clazz) + throws JsonParseException, JsonMappingException, IOException { + + return objectMapper.readValue(json, clazz); + } } diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/LemonAutoConfiguration.java b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/LemonAutoConfiguration.java index 3f99909e..9ebe95b6 100644 --- a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/LemonAutoConfiguration.java +++ b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/LemonAutoConfiguration.java @@ -284,7 +284,7 @@ public LemonUtils lemonUtil(ApplicationContext applicationContext, ObjectMapper objectMapper) { log.info("Configuring LemonUtil"); - return new LemonUtils(applicationContext, objectMapper); + return new LemonUtils(); } /** diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonOAuth2UserService.java b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonOAuth2UserService.java index ce6ac784..7a54c47e 100644 --- a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonOAuth2UserService.java +++ b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonOAuth2UserService.java @@ -15,9 +15,9 @@ import com.naturalprogrammer.spring.lemon.LemonService; import com.naturalprogrammer.spring.lemon.commons.security.LemonPrincipal; import com.naturalprogrammer.spring.lemon.commons.security.UserDto; +import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; import com.naturalprogrammer.spring.lemon.domain.AbstractUser; import com.naturalprogrammer.spring.lemon.exceptions.util.LexUtils; -import com.naturalprogrammer.spring.lemon.util.LemonUtils; /** * Logs in or registers a user after OAuth2 SignIn/Up @@ -67,7 +67,7 @@ public LemonPrincipal buildPrincipal(OAuth2User oath2User, String registrati // register a new user U newUser = lemonService.newUser(); newUser.setEmail(email); - newUser.setPassword(passwordEncoder.encode(LemonUtils.uid())); + newUser.setPassword(passwordEncoder.encode(LecUtils.uid())); lemonService.fillAdditionalFields(registrationId, newUser, attributes); lemonService.save(newUser); diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/util/LemonUtils.java b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/util/LemonUtils.java index f0a60309..569743dd 100644 --- a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/util/LemonUtils.java +++ b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/util/LemonUtils.java @@ -1,11 +1,7 @@ package com.naturalprogrammer.spring.lemon.util; -import java.io.IOException; import java.io.Serializable; -import java.nio.charset.StandardCharsets; import java.util.Optional; -import java.util.Scanner; -import java.util.UUID; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; @@ -13,16 +9,12 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.context.ApplicationContext; -import org.springframework.core.io.Resource; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.transaction.support.TransactionSynchronizationAdapter; import org.springframework.transaction.support.TransactionSynchronizationManager; -import com.fasterxml.jackson.core.JsonParseException; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.JsonMappingException; import com.fasterxml.jackson.databind.ObjectMapper; import com.naturalprogrammer.spring.lemon.commons.security.JwtService; import com.naturalprogrammer.spring.lemon.commons.security.LemonPrincipal; @@ -42,35 +34,12 @@ public class LemonUtils { private static final Log log = LogFactory.getLog(LemonUtils.class); - private static ApplicationContext applicationContext; - private static ObjectMapper objectMapper; - - public LemonUtils(ApplicationContext applicationContext, - ObjectMapper objectMapper) { - - LemonUtils.applicationContext = applicationContext; - LemonUtils.objectMapper = objectMapper; + public LemonUtils() { log.info("Created"); } - public static ObjectMapper getMapper() { - - return objectMapper; - } - - - /** - * Gets the reference to an application-context bean - * - * @param clazz the type of the bean - */ - public static T getBean(Class clazz) { - return applicationContext.getBean(clazz); - } - - /** * Gets the current-user */ @@ -131,34 +100,6 @@ public void afterCommit() { } - /** - * Generates a random unique string - */ - public static String uid() { - - return UUID.randomUUID().toString(); - } - - - /** - * Serializes an object to JSON string - */ - public static String toJson(T obj) throws JsonProcessingException { - - return objectMapper.writeValueAsString(obj); - } - - - /** - * Deserializes a JSON String - */ - public static T fromJson(String json, Class clazz) - throws JsonParseException, JsonMappingException, IOException { - - return objectMapper.readValue(json, clazz); - } - - /** * Throws BadCredentialsException if * user's credentials were updated after the JWT was issued @@ -173,20 +114,6 @@ void ensureCredentialsUpToDate(JWTClaimsSet claims, U user) { } - /** - * Reads a resource into a String - */ - public static String toString(Resource resource) throws IOException { - - String text = null; - try (Scanner scanner = new Scanner(resource.getInputStream(), StandardCharsets.UTF_8.name())) { - text = scanner.useDelimiter("\\A").next(); - } - - return text; - } - - /** * Fetches a cookie from the request */ diff --git a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveController.java b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveController.java index e900a0ab..245b2070 100644 --- a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveController.java +++ b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveController.java @@ -11,6 +11,7 @@ import org.apache.commons.logging.LogFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; import org.springframework.http.server.reactive.ServerHttpResponse; import org.springframework.security.core.Authentication; import org.springframework.security.core.context.ReactiveSecurityContextHolder; @@ -212,7 +213,7 @@ public Mono fetchUserById(@PathVariable ID id) { /** * Updates a user */ - @PatchMapping("/users/{id}") + @PatchMapping(value = "/users/{id}") public Mono> updateUser( @PathVariable ID id, @RequestBody @NotBlank Mono patch, From fc4a711857e713e8b720a2f97e1001eb80f1c6b6 Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Mon, 23 Jul 2018 13:30:19 +0530 Subject: [PATCH 019/116] Coded reactive update user tests --- .../lemondemo/ChangePasswordMvcTests.java | 17 +- .../lemondemo/FetchNewTokenMvcTests.java | 7 +- .../lemondemo/RequestEmailChangeMvcTests.java | 23 +- .../lemondemo/ResetPasswordMvcTests.java | 3 +- .../spring/lemondemo/SignupMvcTests.java | 7 +- .../spring/lemondemo/UpdateUserMvcTests.java | 9 +- .../spring/lemondemo/MyTestUtils.java | 1 - .../spring/lemondemo/UpdateUserTests.java | 201 ++++++++++++++++++ .../spring/lemondemo/UserClient.java | 12 -- .../update-user/patch-admin-role.json | 6 + .../update-user/patch-long-name.json | 4 + .../update-user/patch-null-name.json | 4 + .../update-user/patch-update-user.json | 6 + 13 files changed, 251 insertions(+), 49 deletions(-) create mode 100644 lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/UpdateUserTests.java delete mode 100644 lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/UserClient.java create mode 100644 lemon-demo-reactive/src/test/resources/update-user/patch-admin-role.json create mode 100644 lemon-demo-reactive/src/test/resources/update-user/patch-long-name.json create mode 100644 lemon-demo-reactive/src/test/resources/update-user/patch-null-name.json create mode 100644 lemon-demo-reactive/src/test/resources/update-user/patch-update-user.json diff --git a/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/ChangePasswordMvcTests.java b/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/ChangePasswordMvcTests.java index 6804ab4c..2a1bea99 100644 --- a/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/ChangePasswordMvcTests.java +++ b/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/ChangePasswordMvcTests.java @@ -14,7 +14,6 @@ import com.naturalprogrammer.spring.lemon.commons.domain.ChangePasswordForm; import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; -import com.naturalprogrammer.spring.lemon.util.LemonUtils; @Sql({"/test-data/initialize.sql", "/test-data/finalize.sql"}) public class ChangePasswordMvcTests extends AbstractMvcTests { @@ -40,7 +39,7 @@ public void testChangePassword() throws Exception { mvc.perform(post("/api/core/users/{id}/password", UNVERIFIED_USER_ID) .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, tokens.get(UNVERIFIED_USER_ID)) .contentType(MediaType.APPLICATION_JSON) - .content(LemonUtils.toJson(changePasswordForm(USER_PASSWORD)))) + .content(LecUtils.toJson(changePasswordForm(USER_PASSWORD)))) .andExpect(status().is(204)) .andExpect(header().string(LecUtils.TOKEN_RESPONSE_HEADER_NAME, containsString("."))); @@ -57,7 +56,7 @@ public void testAdminChangePasswordAnotherUser() throws Exception { mvc.perform(post("/api/core/users/{id}/password", UNVERIFIED_USER_ID) .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, tokens.get(ADMIN_ID)) .contentType(MediaType.APPLICATION_JSON) - .content(LemonUtils.toJson(changePasswordForm(ADMIN_PASSWORD)))) + .content(LecUtils.toJson(changePasswordForm(ADMIN_PASSWORD)))) .andExpect(status().is(204)) .andExpect(header().string(LecUtils.TOKEN_RESPONSE_HEADER_NAME, containsString("."))); @@ -74,7 +73,7 @@ public void testChangePasswordUnknownId() throws Exception { mvc.perform(post("/api/core/users/99/password") .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, tokens.get(ADMIN_ID)) .contentType(MediaType.APPLICATION_JSON) - .content(LemonUtils.toJson(changePasswordForm(ADMIN_PASSWORD)))) + .content(LecUtils.toJson(changePasswordForm(ADMIN_PASSWORD)))) .andExpect(status().is(404)); } @@ -87,7 +86,7 @@ public void testChangePasswordAnotherUser() throws Exception { mvc.perform(post("/api/core/users/{id}/password", UNVERIFIED_USER_ID) .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, tokens.get(USER_ID)) .contentType(MediaType.APPLICATION_JSON) - .content(LemonUtils.toJson(changePasswordForm(USER_PASSWORD)))) + .content(LecUtils.toJson(changePasswordForm(USER_PASSWORD)))) .andExpect(status().is(403)); // Ensure password didn't change @@ -103,7 +102,7 @@ public void testBadAdminChangePasswordAnotherUser() throws Exception { mvc.perform(post("/api/core/users/{id}/password", UNVERIFIED_USER_ID) .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, tokens.get(UNVERIFIED_ADMIN_ID)) .contentType(MediaType.APPLICATION_JSON) - .content(LemonUtils.toJson(changePasswordForm(ADMIN_PASSWORD)))) + .content(LecUtils.toJson(changePasswordForm(ADMIN_PASSWORD)))) .andExpect(status().is(403)); // Ensure password didn't change @@ -117,7 +116,7 @@ public void testChangePasswordInvalidData() throws Exception { mvc.perform(post("/api/core/users/{id}/password", UNVERIFIED_USER_ID) .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, tokens.get(UNVERIFIED_USER_ID)) .contentType(MediaType.APPLICATION_JSON) - .content(LemonUtils.toJson(new ChangePasswordForm()))) + .content(LecUtils.toJson(new ChangePasswordForm()))) .andExpect(status().is(422)) .andExpect(jsonPath("$.errors[*].field").value(hasSize(3))) .andExpect(jsonPath("$.errors[*].field").value(hasItems( @@ -134,7 +133,7 @@ public void testChangePasswordInvalidData() throws Exception { mvc.perform(post("/api/core/users/{id}/password", UNVERIFIED_USER_ID) .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, tokens.get(UNVERIFIED_USER_ID)) .contentType(MediaType.APPLICATION_JSON) - .content(LemonUtils.toJson(form))) + .content(LecUtils.toJson(form))) .andExpect(status().is(422)) .andExpect(jsonPath("$.errors[*].field").value(hasSize(3))) .andExpect(jsonPath("$.errors[*].field").value(hasItems( @@ -149,7 +148,7 @@ public void testChangePasswordInvalidData() throws Exception { mvc.perform(post("/api/core/users/{id}/password", UNVERIFIED_USER_ID) .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, tokens.get(UNVERIFIED_USER_ID)) .contentType(MediaType.APPLICATION_JSON) - .content(LemonUtils.toJson(form))) + .content(LecUtils.toJson(form))) .andExpect(status().is(422)) .andExpect(jsonPath("$.errors[*].field").value(hasSize(2))) .andExpect(jsonPath("$.errors[*].field").value(hasItems( diff --git a/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/FetchNewTokenMvcTests.java b/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/FetchNewTokenMvcTests.java index 97f7ca04..a5b8bb69 100644 --- a/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/FetchNewTokenMvcTests.java +++ b/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/FetchNewTokenMvcTests.java @@ -11,7 +11,6 @@ import org.springframework.test.web.servlet.MvcResult; import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; -import com.naturalprogrammer.spring.lemon.util.LemonUtils; public class FetchNewTokenMvcTests extends AbstractMvcTests { @@ -38,7 +37,7 @@ public void testFetchNewToken() throws Exception { .andExpect(jsonPath("$.token").value(containsString("."))) .andReturn(); - Response response = LemonUtils.fromJson(result.getResponse().getContentAsString(), Response.class); + Response response = LecUtils.fromJson(result.getResponse().getContentAsString(), Response.class); ensureTokenWorks(response.getToken()); } @@ -52,7 +51,7 @@ public void testFetchNewTokenExpiration() throws Exception { .andExpect(status().is(200)) .andReturn(); - Response response = LemonUtils.fromJson(result.getResponse().getContentAsString(), Response.class); + Response response = LecUtils.fromJson(result.getResponse().getContentAsString(), Response.class); ensureTokenWorks(response.getToken()); Thread.sleep(1001L); @@ -73,7 +72,7 @@ public void testFetchNewTokenByAdminForAnotherUser() throws Exception { .andExpect(status().is(200)) .andReturn(); - Response response = LemonUtils.fromJson(result.getResponse().getContentAsString(), Response.class); + Response response = LecUtils.fromJson(result.getResponse().getContentAsString(), Response.class); ensureTokenWorks(response.getToken()); } diff --git a/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/RequestEmailChangeMvcTests.java b/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/RequestEmailChangeMvcTests.java index 14e2fff4..75ada58d 100644 --- a/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/RequestEmailChangeMvcTests.java +++ b/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/RequestEmailChangeMvcTests.java @@ -15,7 +15,6 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; -import com.naturalprogrammer.spring.lemon.util.LemonUtils; import com.naturalprogrammer.spring.lemondemo.entities.User; public class RequestEmailChangeMvcTests extends AbstractMvcTests { @@ -37,7 +36,7 @@ public void testRequestEmailChange() throws Exception { mvc.perform(post("/api/core/users/{id}/email-change-request", UNVERIFIED_USER_ID) .contentType(MediaType.APPLICATION_JSON) .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, tokens.get(UNVERIFIED_USER_ID)) - .content(LemonUtils.toJson(form()))) + .content(LecUtils.toJson(form()))) .andExpect(status().is(204)); verify(mailSender).send(any()); @@ -56,7 +55,7 @@ public void testGoodAdminRequestEmailChange() throws Exception { mvc.perform(post("/api/core/users/{id}/email-change-request", UNVERIFIED_USER_ID) .contentType(MediaType.APPLICATION_JSON) .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, tokens.get(ADMIN_ID)) - .content(LemonUtils.toJson(form()))) + .content(LecUtils.toJson(form()))) .andExpect(status().is(204)); User updatedUser = userRepository.findById(UNVERIFIED_USER_ID).get(); @@ -72,7 +71,7 @@ public void testRequestEmailChangeUnknownUser() throws Exception { mvc.perform(post("/api/core/users/99/email-change-request") .contentType(MediaType.APPLICATION_JSON) .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, tokens.get(ADMIN_ID)) - .content(LemonUtils.toJson(form()))) + .content(LecUtils.toJson(form()))) .andExpect(status().is(404)); verify(mailSender, never()).send(any()); @@ -88,7 +87,7 @@ public void testNonAdminRequestEmailChangeAnotherUser() throws Exception { mvc.perform(post("/api/core/users/{id}/email-change-request", ADMIN_ID) .contentType(MediaType.APPLICATION_JSON) .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, tokens.get(USER_ID)) - .content(LemonUtils.toJson(form()))) + .content(LecUtils.toJson(form()))) .andExpect(status().is(403)); verify(mailSender, never()).send(any()); @@ -107,7 +106,7 @@ public void testBadAdminRequestEmailChangeAnotherUser() throws Exception { mvc.perform(post("/api/core/users/{id}/email-change-request", ADMIN_ID) .contentType(MediaType.APPLICATION_JSON) .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, tokens.get(UNVERIFIED_ADMIN_ID)) - .content(LemonUtils.toJson(form()))) + .content(LecUtils.toJson(form()))) .andExpect(status().is(403)); verify(mailSender, never()).send(any()); @@ -125,7 +124,7 @@ public void tryingWithInvalidData() throws JsonProcessingException, Exception { mvc.perform(post("/api/core/users/{id}/email-change-request", UNVERIFIED_USER_ID) .contentType(MediaType.APPLICATION_JSON) .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, tokens.get(UNVERIFIED_USER_ID)) - .content(LemonUtils.toJson(new User()))) + .content(LecUtils.toJson(new User()))) .andExpect(status().is(422)) .andExpect(jsonPath("$.errors[*].field").value(hasSize(2))) .andExpect(jsonPath("$.errors[*].field").value(hasItems( @@ -140,7 +139,7 @@ public void tryingWithInvalidData() throws JsonProcessingException, Exception { mvc.perform(post("/api/core/users/{id}/email-change-request", UNVERIFIED_USER_ID) .contentType(MediaType.APPLICATION_JSON) .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, tokens.get(UNVERIFIED_USER_ID)) - .content(LemonUtils.toJson(updatedUser))) + .content(LecUtils.toJson(updatedUser))) .andExpect(status().is(422)) .andExpect(jsonPath("$.errors[*].field").value(hasSize(4))) .andExpect(jsonPath("$.errors[*].field").value(hasItems( @@ -153,7 +152,7 @@ public void tryingWithInvalidData() throws JsonProcessingException, Exception { mvc.perform(post("/api/core/users/{id}/email-change-request", UNVERIFIED_USER_ID) .contentType(MediaType.APPLICATION_JSON) .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, tokens.get(UNVERIFIED_USER_ID)) - .content(LemonUtils.toJson(updatedUser))) + .content(LecUtils.toJson(updatedUser))) .andExpect(status().is(422)) .andExpect(jsonPath("$.errors[*].field").value(hasSize(1))) .andExpect(jsonPath("$.errors[*].field").value(hasItems("updatedUser.newEmail"))); @@ -164,7 +163,7 @@ public void tryingWithInvalidData() throws JsonProcessingException, Exception { mvc.perform(post("/api/core/users/{id}/email-change-request", UNVERIFIED_USER_ID) .contentType(MediaType.APPLICATION_JSON) .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, tokens.get(UNVERIFIED_USER_ID)) - .content(LemonUtils.toJson(updatedUser))) + .content(LecUtils.toJson(updatedUser))) .andExpect(status().is(422)) .andExpect(jsonPath("$.errors[*].field").value(hasSize(1))) .andExpect(jsonPath("$.errors[*].field").value(hasItems("updatedUser.password"))); @@ -175,7 +174,7 @@ public void tryingWithInvalidData() throws JsonProcessingException, Exception { mvc.perform(post("/api/core/users/{id}/email-change-request", UNVERIFIED_USER_ID) .contentType(MediaType.APPLICATION_JSON) .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, tokens.get(UNVERIFIED_USER_ID)) - .content(LemonUtils.toJson(updatedUser))) + .content(LecUtils.toJson(updatedUser))) .andExpect(status().is(422)) .andExpect(jsonPath("$.errors[*].field").value(hasSize(1))) .andExpect(jsonPath("$.errors[*].field").value(hasItems("updatedUser.password"))); @@ -186,7 +185,7 @@ public void tryingWithInvalidData() throws JsonProcessingException, Exception { mvc.perform(post("/api/core/users/{id}/email-change-request", UNVERIFIED_USER_ID) .contentType(MediaType.APPLICATION_JSON) .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, tokens.get(UNVERIFIED_USER_ID)) - .content(LemonUtils.toJson(updatedUser))) + .content(LecUtils.toJson(updatedUser))) .andExpect(status().is(422)) .andExpect(jsonPath("$.errors[*].field").value(hasSize(1))) .andExpect(jsonPath("$.errors[*].field").value(hasItems("updatedUser.newEmail"))); diff --git a/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/ResetPasswordMvcTests.java b/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/ResetPasswordMvcTests.java index 801add24..d55d243f 100644 --- a/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/ResetPasswordMvcTests.java +++ b/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/ResetPasswordMvcTests.java @@ -15,7 +15,6 @@ import com.naturalprogrammer.spring.lemon.commons.domain.ResetPasswordForm; import com.naturalprogrammer.spring.lemon.commons.security.JwtService; import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; -import com.naturalprogrammer.spring.lemon.util.LemonUtils; public class ResetPasswordMvcTests extends AbstractMvcTests { @@ -84,6 +83,6 @@ private String form(String code, String newPassword) throws JsonProcessingExcept form.setCode(code); form.setNewPassword(newPassword); - return LemonUtils.toJson(form); + return LecUtils.toJson(form); } } diff --git a/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/SignupMvcTests.java b/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/SignupMvcTests.java index 5282f0be..555df548 100644 --- a/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/SignupMvcTests.java +++ b/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/SignupMvcTests.java @@ -17,7 +17,6 @@ import org.springframework.test.context.jdbc.Sql; import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; -import com.naturalprogrammer.spring.lemon.util.LemonUtils; import com.naturalprogrammer.spring.lemondemo.entities.User; @Sql({"/test-data/initialize.sql", "/test-data/finalize.sql"}) @@ -30,7 +29,7 @@ public void testSignupWithInvalidData() throws Exception { mvc.perform(post("/api/core/users") .contentType(MediaType.APPLICATION_JSON) - .content(LemonUtils.toJson(invalidUser))) + .content(LecUtils.toJson(invalidUser))) .andExpect(status().is(422)) .andExpect(jsonPath("$.errors[*].field").value(hasSize(4))) .andExpect(jsonPath("$.errors[*].field").value(hasItems( @@ -46,7 +45,7 @@ public void testSignup() throws Exception { mvc.perform(post("/api/core/users") .contentType(MediaType.APPLICATION_JSON) - .content(LemonUtils.toJson(user))) + .content(LecUtils.toJson(user))) .andExpect(status().is(201)) .andExpect(header().string(LecUtils.TOKEN_RESPONSE_HEADER_NAME, containsString("."))) .andExpect(jsonPath("$.id").exists()) @@ -74,7 +73,7 @@ public void testSignupDuplicateEmail() throws Exception { mvc.perform(post("/api/core/users") .contentType(MediaType.APPLICATION_JSON) - .content(LemonUtils.toJson(user))) + .content(LecUtils.toJson(user))) .andExpect(status().is(422)); verify(mailSender, never()).send(any()); diff --git a/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/UpdateUserMvcTests.java b/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/UpdateUserMvcTests.java index 618e66b5..5038a62e 100644 --- a/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/UpdateUserMvcTests.java +++ b/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/UpdateUserMvcTests.java @@ -18,7 +18,6 @@ import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; import com.naturalprogrammer.spring.lemon.commons.util.UserUtils; -import com.naturalprogrammer.spring.lemon.util.LemonUtils; import com.naturalprogrammer.spring.lemondemo.entities.User; @Sql({"/test-data/initialize.sql", "/test-data/finalize.sql"}) @@ -33,22 +32,22 @@ public class UpdateUserMvcTests extends AbstractMvcTests { @Value("classpath:/update-user/patch-update-user.json") public void setUserPatch(Resource patch) throws IOException { - this.userPatch = LemonUtils.toString(patch); + this.userPatch = LecUtils.toStr(patch); } @Value("classpath:/update-user/patch-admin-role.json") public void setUserPatchAdminRole(Resource patch) throws IOException { - this.userPatchAdminRole = LemonUtils.toString(patch);; + this.userPatchAdminRole = LecUtils.toStr(patch);; } @Value("classpath:/update-user/patch-null-name.json") public void setUserPatchNullName(Resource patch) throws IOException { - this.userPatchNullName = LemonUtils.toString(patch);; + this.userPatchNullName = LecUtils.toStr(patch);; } @Value("classpath:/update-user/patch-long-name.json") public void setUserPatchLongName(Resource patch) throws IOException { - this.userPatchLongName = LemonUtils.toString(patch);; + this.userPatchLongName = LecUtils.toStr(patch);; } /** diff --git a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/MyTestUtils.java b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/MyTestUtils.java index 781b8fd3..54144ea2 100644 --- a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/MyTestUtils.java +++ b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/MyTestUtils.java @@ -122,7 +122,6 @@ private void createUser(ObjectId id, String email, String password, String name, user.setPassword(passwordEncoder.encode(password)); user.setName(name); user.setCredentialsUpdatedMillis(0L); - user.setVersion(1L); user.setRoles(new HashSet(Arrays.asList(roles))); mongoTemplate.insert(user); diff --git a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/UpdateUserTests.java b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/UpdateUserTests.java new file mode 100644 index 00000000..1eb05ba8 --- /dev/null +++ b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/UpdateUserTests.java @@ -0,0 +1,201 @@ +package com.naturalprogrammer.spring.lemondemo; + +import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.ADMIN_ID; +import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.BLOCKED_ADMIN_ID; +import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.CLIENT; +import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.TOKENS; +import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.UNVERIFIED_ADMIN_ID; +import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.UNVERIFIED_USER_EMAIL; +import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.UNVERIFIED_USER_ID; +import static com.naturalprogrammer.spring.lemondemo.controllers.MyController.BASE_URI; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import org.bson.types.ObjectId; +import org.junit.Test; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.core.io.Resource; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.test.web.reactive.server.WebTestClient.ResponseSpec; +import org.springframework.web.reactive.function.BodyInserters; + +import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; +import com.naturalprogrammer.spring.lemon.commons.util.UserUtils; +import com.naturalprogrammer.spring.lemondemo.domain.User; +import com.naturalprogrammer.spring.lemondemo.dto.TestUserDto; + +public class UpdateUserTests extends AbstractTests { + + private static final String UPDATED_NAME = "Edited name"; + + @Value("classpath:/update-user/patch-update-user.json") + private Resource userPatch; + + @Value("classpath:/update-user/patch-admin-role.json") + private Resource userPatchAdminRole; + + @Value("classpath:/update-user/patch-null-name.json") + private Resource userPatchNullName; + + @Value("classpath:/update-user/patch-long-name.json") + private Resource userPatchLongName; + + /** + * A non-admin user should be able to update his own name, + * but changes in roles should be skipped. + * The name of security principal object should also + * change in the process. + * @throws Exception + */ + @Test + public void testUpdateSelf() throws Exception { + + updateUser(UNVERIFIED_USER_ID, UNVERIFIED_USER_ID, userPatch) + .expectStatus().isOk() + .expectHeader().exists(LecUtils.TOKEN_RESPONSE_HEADER_NAME) + .expectBody(TestUserDto.class) + .consumeWith(result -> { + + TestUserDto userDto = result.getResponseBody(); + + assertEquals(UNVERIFIED_USER_ID, userDto.getId()); + assertEquals(UNVERIFIED_USER_EMAIL, userDto.getUsername()); + assertEquals(UPDATED_NAME, userDto.getTag().getName()); + assertEquals(1, userDto.getRoles().size()); + assertTrue(userDto.getRoles().contains(UserUtils.Role.UNVERIFIED)); + }); + + User user = mongoTemplate.findById(UNVERIFIED_USER_ID, User.class); + + // Ensure that data changed properly + assertEquals(UNVERIFIED_USER_EMAIL, user.getEmail()); + assertEquals(1, user.getRoles().size()); + assertTrue(user.getRoles().contains(UserUtils.Role.UNVERIFIED)); + assertEquals(1L, user.getVersion()); + + // Version mismatch + updateUser(UNVERIFIED_USER_ID, UNVERIFIED_USER_ID, userPatch) + .expectStatus().isEqualTo(HttpStatus.CONFLICT); + } + + + /** + * A good ADMIN should be able to update another user's name and roles. + * The name of security principal object should NOT change in the process, + * and the verification code should get set/unset on addition/deletion of + * the UNVERIFIED role. + * @throws Exception + */ + @Test + public void testGoodAdminCanUpdateOther() throws Exception { + + updateUser(UNVERIFIED_USER_ID, ADMIN_ID, userPatch) + .expectStatus().isOk() + .expectHeader().exists(LecUtils.TOKEN_RESPONSE_HEADER_NAME) + .expectBody(TestUserDto.class) + .consumeWith(result -> { + + TestUserDto userDto = result.getResponseBody(); + + assertEquals(UNVERIFIED_USER_ID, userDto.getId()); + assertEquals(UNVERIFIED_USER_EMAIL, userDto.getUsername()); + assertEquals(UPDATED_NAME, userDto.getTag().getName()); + assertEquals(1, userDto.getRoles().size()); + assertTrue(userDto.getRoles().contains(UserUtils.Role.ADMIN)); + }); + + User user = mongoTemplate.findById(UNVERIFIED_USER_ID, User.class); + + // Ensure that data changed properly + assertEquals(UNVERIFIED_USER_EMAIL, user.getEmail()); + assertEquals(1, user.getRoles().size()); + assertTrue(user.getRoles().contains(UserUtils.Role.ADMIN)); + } + + /** + * Providing an unknown id should return 404. + */ + @Test + public void testUpdateUnknownId() throws Exception { + + updateUser(ObjectId.get(), ADMIN_ID, userPatch) + .expectStatus().isNotFound(); + } + + /** + * A non-admin trying to update the name and roles of another user should throw exception + * @throws Exception + */ + @Test + public void testUpdateAnotherUser() throws Exception { + + updateUser(ADMIN_ID, UNVERIFIED_USER_ID, userPatch) + .expectStatus().isForbidden(); + } + + /** + * A bad ADMIN trying to update the name and roles of another user should throw exception + * @throws Exception + */ + @Test + public void testBadAdminUpdateAnotherUser() throws Exception { + + updateUser(UNVERIFIED_USER_ID, UNVERIFIED_ADMIN_ID, userPatch) + .expectStatus().isForbidden(); + + updateUser(UNVERIFIED_USER_ID, BLOCKED_ADMIN_ID, userPatch) + .expectStatus().isForbidden(); + } + + /** + * A good ADMIN should not be able to change his own roles + * @throws Exception + */ + @Test + public void goodAdminCanNotUpdateSelfRoles() throws Exception { + + updateUser(ADMIN_ID, ADMIN_ID, userPatchAdminRole) + .expectStatus().isOk() + .expectHeader().exists(LecUtils.TOKEN_RESPONSE_HEADER_NAME) + .expectBody(TestUserDto.class) + .consumeWith(result -> { + + TestUserDto userDto = result.getResponseBody(); + + assertEquals(UPDATED_NAME, userDto.getTag().getName()); + assertEquals(1, userDto.getRoles().size()); + assertTrue(userDto.getRoles().contains(UserUtils.Role.ADMIN)); + }); + + User user = mongoTemplate.findById(ADMIN_ID, User.class); + + assertEquals(1, user.getRoles().size()); + } + + /** + * Invalid name + * @throws Exception + */ + @Test + public void testUpdateUserInvalidNewName() throws Exception { + + // Null name + updateUser(UNVERIFIED_USER_ID, ADMIN_ID, userPatchNullName) + .expectStatus().isEqualTo(HttpStatus.UNPROCESSABLE_ENTITY); + + // Too long name + updateUser(UNVERIFIED_USER_ID, UNVERIFIED_USER_ID, userPatchLongName) + .expectStatus().isEqualTo(HttpStatus.UNPROCESSABLE_ENTITY); + } + + private ResponseSpec updateUser(ObjectId userId, ObjectId loggedInId, Resource patch) { + + return CLIENT.patch().uri(BASE_URI + "/users/{id}", userId) + .contentType(MediaType.APPLICATION_JSON) + .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, TOKENS.get(loggedInId)) + .body(BodyInserters.fromResource(patch)) + .exchange(); + + } +} diff --git a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/UserClient.java b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/UserClient.java deleted file mode 100644 index 28da1912..00000000 --- a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/UserClient.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.naturalprogrammer.spring.lemondemo; - -import org.springframework.stereotype.Component; - -import com.naturalprogrammer.spring.lemondemo.controllers.MyController; - -@Component -public class UserClient { - - public static String USER_URI = MyController.BASE_URI + "/users"; - -} diff --git a/lemon-demo-reactive/src/test/resources/update-user/patch-admin-role.json b/lemon-demo-reactive/src/test/resources/update-user/patch-admin-role.json new file mode 100644 index 00000000..541a71f9 --- /dev/null +++ b/lemon-demo-reactive/src/test/resources/update-user/patch-admin-role.json @@ -0,0 +1,6 @@ +[ + {"op": "replace", "path": "/name", "value": "Edited name"}, + {"op": "replace", "path": "/email", "value": "should.not@get.replaced"}, + {"op": "replace", "path": "/roles", "value": []}, + {"op": "replace", "path": "/version", "value": 0} +] diff --git a/lemon-demo-reactive/src/test/resources/update-user/patch-long-name.json b/lemon-demo-reactive/src/test/resources/update-user/patch-long-name.json new file mode 100644 index 00000000..62e0d730 --- /dev/null +++ b/lemon-demo-reactive/src/test/resources/update-user/patch-long-name.json @@ -0,0 +1,4 @@ +[ + {"op": "replace", "path": "/name", "value": "A123456789A123456789A123456789A123456789A123456789A123456789A123456789"}, + {"op": "replace", "path": "/version", "value": 0} +] diff --git a/lemon-demo-reactive/src/test/resources/update-user/patch-null-name.json b/lemon-demo-reactive/src/test/resources/update-user/patch-null-name.json new file mode 100644 index 00000000..9fc08cb5 --- /dev/null +++ b/lemon-demo-reactive/src/test/resources/update-user/patch-null-name.json @@ -0,0 +1,4 @@ +[ + {"op": "replace", "path": "/name", "value": null}, + {"op": "replace", "path": "/version", "value": 0} +] diff --git a/lemon-demo-reactive/src/test/resources/update-user/patch-update-user.json b/lemon-demo-reactive/src/test/resources/update-user/patch-update-user.json new file mode 100644 index 00000000..228cc7c5 --- /dev/null +++ b/lemon-demo-reactive/src/test/resources/update-user/patch-update-user.json @@ -0,0 +1,6 @@ +[ + {"op": "replace", "path": "/name", "value": "Edited name"}, + {"op": "replace", "path": "/email", "value": "should.not@get.replaced"}, + {"op": "replace", "path": "/roles", "value": ["ADMIN"]}, + {"op": "replace", "path": "/version", "value": 0} +] From 97188d3be8fec643dfa5ea3031a0fd7407021963 Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Mon, 23 Jul 2018 15:42:56 +0530 Subject: [PATCH 020/116] Coded reactive verification tests --- .../lemondemo/VerificationMvcTests.java | 3 +- .../spring/lemondemo/VerificationTests.java | 107 ++++++++++++++++++ 2 files changed, 108 insertions(+), 2 deletions(-) create mode 100644 lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/VerificationTests.java diff --git a/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/VerificationMvcTests.java b/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/VerificationMvcTests.java index 4d101276..7f9046ca 100644 --- a/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/VerificationMvcTests.java +++ b/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/VerificationMvcTests.java @@ -56,8 +56,7 @@ public void testEmailVerificationNonExistingUser() throws Exception { mvc.perform(post("/api/core/users/99/verification") .param("code", verificationCode) - .header("contentType", MediaType.APPLICATION_FORM_URLENCODED) - .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, tokens.get(UNVERIFIED_USER_ID))) + .header("contentType", MediaType.APPLICATION_FORM_URLENCODED)) .andExpect(status().is(404)); } diff --git a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/VerificationTests.java b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/VerificationTests.java new file mode 100644 index 00000000..4f4faa41 --- /dev/null +++ b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/VerificationTests.java @@ -0,0 +1,107 @@ +package com.naturalprogrammer.spring.lemondemo; + +import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.CLIENT; +import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.UNVERIFIED_USER_EMAIL; +import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.UNVERIFIED_USER_ID; +import static com.naturalprogrammer.spring.lemondemo.controllers.MyController.BASE_URI; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.springframework.web.reactive.function.BodyInserters.fromFormData; + +import org.bson.types.ObjectId; +import org.junit.Before; +import org.junit.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.test.web.reactive.server.WebTestClient.ResponseSpec; + +import com.naturalprogrammer.spring.lemon.commons.security.JwtService; +import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; +import com.naturalprogrammer.spring.lemondemo.dto.TestUserDto; + +public class VerificationTests extends AbstractTests { + + private String verificationCode; + + @Autowired + private JwtService jwtService; + + @Before + public void setUp() { + + verificationCode = jwtService.createToken(JwtService.VERIFY_AUDIENCE, + UNVERIFIED_USER_ID.toString(), 60000L, + LecUtils.mapOf("email", UNVERIFIED_USER_EMAIL)); + } + + @Test + public void testEmailVerification() throws Exception { + + emailVerification(UNVERIFIED_USER_ID, verificationCode) + .expectStatus().isOk() + .expectHeader().exists(LecUtils.TOKEN_RESPONSE_HEADER_NAME) + .expectBody(TestUserDto.class) + .consumeWith(result -> { + + TestUserDto userDto = result.getResponseBody(); + + assertEquals(UNVERIFIED_USER_ID, userDto.getId()); + assertEquals(0, userDto.getRoles().size()); + assertTrue(userDto.isGoodUser()); + assertFalse(userDto.isUnverified()); + }); + + // Already verified + emailVerification(UNVERIFIED_USER_ID, verificationCode) + .expectStatus().isEqualTo(HttpStatus.UNPROCESSABLE_ENTITY); + } + + @Test + public void testEmailVerificationNonExistingUser() throws Exception { + + emailVerification(ObjectId.get(), verificationCode) + .expectStatus().isNotFound(); + } + + @Test + public void testEmailVerificationWrongToken() throws Exception { + + // null token + CLIENT.post().uri(BASE_URI + "/users/{id}/verification", UNVERIFIED_USER_ID) + .exchange() + .expectStatus().isEqualTo(HttpStatus.UNPROCESSABLE_ENTITY); + + // blank token + emailVerification(UNVERIFIED_USER_ID, "") + .expectStatus().isEqualTo(HttpStatus.UNPROCESSABLE_ENTITY); + + // Wrong audience + String token = jwtService.createToken("wrong-audience", + UNVERIFIED_USER_ID.toString(), 60000L, + LecUtils.mapOf("email", UNVERIFIED_USER_EMAIL)); + emailVerification(UNVERIFIED_USER_ID, token) + .expectStatus().isUnauthorized(); + + // Wrong email + token = jwtService.createToken(JwtService.VERIFY_AUDIENCE, + UNVERIFIED_USER_ID.toString(), 60000L, + LecUtils.mapOf("email", "wrong.email@example.com")); + emailVerification(UNVERIFIED_USER_ID, token) + .expectStatus().isForbidden(); + + // expired token + token = jwtService.createToken(JwtService.VERIFY_AUDIENCE, + UNVERIFIED_USER_ID.toString(), 1L, + LecUtils.mapOf("email", UNVERIFIED_USER_EMAIL)); + emailVerification(UNVERIFIED_USER_ID, token) + .expectStatus().isUnauthorized(); + } + + private ResponseSpec emailVerification(ObjectId userId, String code) { + + return CLIENT.post().uri(BASE_URI + "/users/{id}/verification", userId) + .body(fromFormData("code", code)) + .exchange(); + } +} From 250f75032fd409c35e0e8bae3d82fab4789a5653 Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Mon, 23 Jul 2018 17:51:20 +0530 Subject: [PATCH 021/116] Added captcha to reactive project, etc. --- .../app/scripts/services/formservice.js | 15 +++++++- .../lemon/commons}/validation/Captcha.java | 2 +- .../commons}/validation/CaptchaValidator.java | 2 +- .../spring/lemon/LemonAutoConfiguration.java | 2 +- .../spring/lemon/domain/AbstractUser.java | 2 +- .../LemonReactiveAutoConfiguration.java | 17 +++++++++ .../domain/AbstractMongoUser.java | 2 + .../security/LemonReactiveCorsConfig.java | 37 +++++++++++++++++++ 8 files changed, 73 insertions(+), 6 deletions(-) rename {spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon => spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons}/validation/Captcha.java (92%) rename {spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon => spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons}/validation/CaptchaValidator.java (98%) create mode 100644 spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/security/LemonReactiveCorsConfig.java diff --git a/lemon-demo-angularjs/app/scripts/services/formservice.js b/lemon-demo-angularjs/app/scripts/services/formservice.js index 83dccd02..c4127020 100644 --- a/lemon-demo-angularjs/app/scripts/services/formservice.js +++ b/lemon-demo-angularjs/app/scripts/services/formservice.js @@ -10,7 +10,16 @@ angular.module('appBoot') .factory('formService', function($http, $location, alerts) { - /** + var serialize = function(obj) { + var str = []; + for (var p in obj) + if (obj.hasOwnProperty(p)) { + str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p])); + } + return str.join("&"); + } + + /** * Creates the array if not already present * * @param obj @@ -30,6 +39,8 @@ angular.module('appBoot') switch (errorData.exception) { case 'ConstraintViolationException': // server side JSR-303 errors + case 'ExplicitConstraintViolationException': // server side JSR-303 errors + case 'WebExchangeBindException': // server side JSR-303 errors case 'MultiErrorException': // server side form errors manually thrown angular.forEach(errorData.errors, function(error) { // for each fields @@ -72,7 +83,7 @@ angular.module('appBoot') if (method === 'post' || method === 'put' || method === 'patch') { if (options.asParam) // data should be sent as params - return $http[method](serverUrl + url, null, {params: options.data}); + return $http[method](serverUrl + url, serialize(options.data), {headers: {'Content-Type': 'application/x-www-form-urlencoded'}}); return $http[method](serverUrl + url, options.data); } diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/validation/Captcha.java b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/validation/Captcha.java similarity index 92% rename from spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/validation/Captcha.java rename to spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/validation/Captcha.java index 7c848b1e..df325703 100644 --- a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/validation/Captcha.java +++ b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/validation/Captcha.java @@ -1,4 +1,4 @@ -package com.naturalprogrammer.spring.lemon.validation; +package com.naturalprogrammer.spring.lemon.commons.validation; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/validation/CaptchaValidator.java b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/validation/CaptchaValidator.java similarity index 98% rename from spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/validation/CaptchaValidator.java rename to spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/validation/CaptchaValidator.java index ce2bac86..fac328f9 100644 --- a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/validation/CaptchaValidator.java +++ b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/validation/CaptchaValidator.java @@ -1,4 +1,4 @@ -package com.naturalprogrammer.spring.lemon.validation; +package com.naturalprogrammer.spring.lemon.commons.validation; import java.util.Collection; diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/LemonAutoConfiguration.java b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/LemonAutoConfiguration.java index 9ebe95b6..7284f472 100644 --- a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/LemonAutoConfiguration.java +++ b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/LemonAutoConfiguration.java @@ -35,6 +35,7 @@ import com.naturalprogrammer.spring.lemon.commons.LemonCommonsAutoConfiguration; import com.naturalprogrammer.spring.lemon.commons.LemonProperties; import com.naturalprogrammer.spring.lemon.commons.security.JwtService; +import com.naturalprogrammer.spring.lemon.commons.validation.CaptchaValidator; import com.naturalprogrammer.spring.lemon.commons.validation.RetypePasswordValidator; import com.naturalprogrammer.spring.lemon.domain.AbstractUser; import com.naturalprogrammer.spring.lemon.domain.AbstractUserRepository; @@ -53,7 +54,6 @@ import com.naturalprogrammer.spring.lemon.security.OAuth2AuthenticationFailureHandler; import com.naturalprogrammer.spring.lemon.security.OAuth2AuthenticationSuccessHandler; import com.naturalprogrammer.spring.lemon.util.LemonUtils; -import com.naturalprogrammer.spring.lemon.validation.CaptchaValidator; import com.naturalprogrammer.spring.lemon.validation.UniqueEmailValidator; /** diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/domain/AbstractUser.java b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/domain/AbstractUser.java index 7683e1d5..0074bfa7 100644 --- a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/domain/AbstractUser.java +++ b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/domain/AbstractUser.java @@ -16,8 +16,8 @@ import com.fasterxml.jackson.annotation.JsonView; import com.naturalprogrammer.spring.lemon.commons.security.UserDto; import com.naturalprogrammer.spring.lemon.commons.util.UserUtils; +import com.naturalprogrammer.spring.lemon.commons.validation.Captcha; import com.naturalprogrammer.spring.lemon.commons.validation.Password; -import com.naturalprogrammer.spring.lemon.validation.Captcha; import com.naturalprogrammer.spring.lemon.validation.UniqueEmail; import lombok.Getter; diff --git a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveAutoConfiguration.java b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveAutoConfiguration.java index 4730612b..d65ef51c 100644 --- a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveAutoConfiguration.java +++ b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveAutoConfiguration.java @@ -7,6 +7,7 @@ import org.bson.types.ObjectId; import org.springframework.boot.autoconfigure.AutoConfigureBefore; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.autoconfigure.mongo.MongoReactiveAutoConfiguration; import org.springframework.boot.autoconfigure.security.reactive.ReactiveSecurityAutoConfiguration; import org.springframework.boot.autoconfigure.security.reactive.ReactiveUserDetailsServiceAutoConfiguration; @@ -27,6 +28,7 @@ import com.fasterxml.jackson.databind.module.SimpleModule; import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; import com.naturalprogrammer.spring.lemon.commons.LemonCommonsAutoConfiguration; +import com.naturalprogrammer.spring.lemon.commons.LemonProperties; import com.naturalprogrammer.spring.lemon.commons.security.JwtService; import com.naturalprogrammer.spring.lemon.exceptions.ErrorResponseComposer; import com.naturalprogrammer.spring.lemon.exceptions.util.LexUtils; @@ -34,6 +36,7 @@ import com.naturalprogrammer.spring.lemonreactive.domain.AbstractMongoUserRepository; import com.naturalprogrammer.spring.lemonreactive.exceptions.LemonReactiveErrorAttributes; import com.naturalprogrammer.spring.lemonreactive.exceptions.handlers.VersionExceptionHandler; +import com.naturalprogrammer.spring.lemonreactive.security.LemonReactiveCorsConfig; import com.naturalprogrammer.spring.lemonreactive.security.LemonReactiveSecurityConfig; import com.naturalprogrammer.spring.lemonreactive.security.LemonReactiveUserDetailsService; import com.naturalprogrammer.spring.lemonreactive.util.LerUtils; @@ -115,6 +118,20 @@ LemonReactiveUserDetailsService userDetailService(AbstractMongoUserReposi return new LemonReactiveUserDetailsService(userRepository); } + + /** + * Configures LemonCorsConfig if missing and lemon.cors.allowed-origins is provided + */ + @Bean + @ConditionalOnProperty(name="lemon.cors.allowed-origins") + @ConditionalOnMissingBean(LemonReactiveCorsConfig.class) + public LemonReactiveCorsConfig lemonCorsConfig(LemonProperties properties) { + + log.info("Configuring LemonCorsConfig"); + return new LemonReactiveCorsConfig(properties); + } + + @Bean public SimpleModule objectIdModule() { diff --git a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/domain/AbstractMongoUser.java b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/domain/AbstractMongoUser.java index 8878c168..138f93ba 100644 --- a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/domain/AbstractMongoUser.java +++ b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/domain/AbstractMongoUser.java @@ -12,6 +12,7 @@ import com.fasterxml.jackson.annotation.JsonView; import com.naturalprogrammer.spring.lemon.commons.security.UserDto; import com.naturalprogrammer.spring.lemon.commons.util.UserUtils; +import com.naturalprogrammer.spring.lemon.commons.validation.Captcha; import com.naturalprogrammer.spring.lemon.commons.validation.Password; import com.naturalprogrammer.spring.lemonreactive.validation.UniqueEmail; @@ -45,6 +46,7 @@ public abstract class AbstractMongoUser // holds reCAPTCHA response while signing up @Transient @JsonView(UserUtils.SignupInput.class) + @Captcha private String captchaResponse; public final boolean hasRole(String role) { diff --git a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/security/LemonReactiveCorsConfig.java b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/security/LemonReactiveCorsConfig.java new file mode 100644 index 00000000..9c1e441c --- /dev/null +++ b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/security/LemonReactiveCorsConfig.java @@ -0,0 +1,37 @@ +package com.naturalprogrammer.spring.lemonreactive.security; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.springframework.web.reactive.config.CorsRegistry; +import org.springframework.web.reactive.config.WebFluxConfigurer; + +import com.naturalprogrammer.spring.lemon.commons.LemonProperties; +import com.naturalprogrammer.spring.lemon.commons.LemonProperties.Cors; + +/** + * CORS Configuration + */ +public class LemonReactiveCorsConfig implements WebFluxConfigurer { + + private static final Log log = LogFactory.getLog(LemonReactiveCorsConfig.class); + + private Cors cors; + + public LemonReactiveCorsConfig(LemonProperties properties) { + + this.cors = properties.getCors(); + log.info("Created"); + } + + @Override + public void addCorsMappings(CorsRegistry registry) { + + registry.addMapping("/**") + .allowedOrigins(cors.getAllowedOrigins()) + .allowedMethods(cors.getAllowedMethods()) + .allowedHeaders(cors.getAllowedHeaders()) + .exposedHeaders(cors.getExposedHeaders()) + .allowCredentials(true) + .maxAge(cors.getMaxAge()); + } +} From c0ebb4e50f3733125d662bf752bed45d81c9cb02 Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Mon, 23 Jul 2018 18:16:16 +0530 Subject: [PATCH 022/116] Coded #20: Replace all LecUtils.TOKEN_REQUEST_HEADER_NAME with HttpHeaders.AUTHORIZATION --- .../spring/lemondemo/AbstractMvcTests.java | 3 ++- .../spring/lemondemo/BasicMvcTests.java | 3 ++- .../spring/lemondemo/ChangeEmailMvcTests.java | 19 +++++++-------- .../lemondemo/ChangePasswordMvcTests.java | 17 +++++++------- .../lemondemo/FetchNewTokenMvcTests.java | 11 +++++---- .../spring/lemondemo/FetchUserMvcTests.java | 7 +++--- .../spring/lemondemo/LoginMvcTests.java | 9 ++++---- .../lemondemo/RequestEmailChangeMvcTests.java | 23 ++++++++++--------- .../ResendVerificationMailMvcTests.java | 15 ++++++------ .../spring/lemondemo/UpdateUserMvcTests.java | 21 +++++++++-------- .../spring/lemondemo/ChangeEmailTests.java | 7 +++--- .../spring/lemondemo/ChangePasswordTests.java | 17 +++++++------- .../spring/lemondemo/FetchNewTokenTests.java | 11 +++++---- .../spring/lemondemo/FetchUserTests.java | 7 +++--- .../spring/lemondemo/LoginTests.java | 9 ++++---- .../spring/lemondemo/MyTestUtils.java | 3 ++- .../lemondemo/RequestEmailChangeTests.java | 13 ++++++----- .../ResendVerificationMailTests.java | 3 ++- .../spring/lemondemo/UpdateUserTests.java | 3 ++- .../spring/lemon/commons/LemonProperties.java | 3 ++- .../spring/lemon/commons/util/LecUtils.java | 1 - .../LemonTokenAuthenticationFilter.java | 5 ++-- 22 files changed, 115 insertions(+), 95 deletions(-) diff --git a/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/AbstractMvcTests.java b/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/AbstractMvcTests.java index 2753bdd8..5d8f9926 100644 --- a/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/AbstractMvcTests.java +++ b/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/AbstractMvcTests.java @@ -16,6 +16,7 @@ import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.mock.mockito.SpyBean; +import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; import org.springframework.test.context.jdbc.Sql; import org.springframework.test.context.junit4.SpringRunner; @@ -89,7 +90,7 @@ public void baseSetUp() throws Exception { protected void ensureTokenWorks(String token) throws Exception { mvc.perform(get("/api/core/context") - .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, token)) + .header(HttpHeaders.AUTHORIZATION, token)) .andExpect(status().is(200)) .andExpect(jsonPath("$.user.id").value(UNVERIFIED_USER_ID)); } diff --git a/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/BasicMvcTests.java b/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/BasicMvcTests.java index b2e24856..fec54da0 100644 --- a/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/BasicMvcTests.java +++ b/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/BasicMvcTests.java @@ -7,6 +7,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; import org.junit.Test; +import org.springframework.http.HttpHeaders; import org.springframework.test.context.jdbc.Sql; import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; @@ -25,7 +26,7 @@ public void testPing() throws Exception { public void testGetContextLoggedIn() throws Exception { mvc.perform(get("/api/core/context") - .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, tokens.get(ADMIN_ID))) + .header(HttpHeaders.AUTHORIZATION, tokens.get(ADMIN_ID))) .andExpect(status().is(200)) .andExpect(header().string(LecUtils.TOKEN_RESPONSE_HEADER_NAME, containsString("."))) .andExpect(jsonPath("$.context.reCaptchaSiteKey").isString()) diff --git a/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/ChangeEmailMvcTests.java b/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/ChangeEmailMvcTests.java index c1c371ca..0bee2e3b 100644 --- a/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/ChangeEmailMvcTests.java +++ b/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/ChangeEmailMvcTests.java @@ -10,6 +10,7 @@ import org.junit.Before; import org.junit.Test; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; import com.naturalprogrammer.spring.lemon.commons.security.JwtService; @@ -43,7 +44,7 @@ public void testChangeEmail() throws Exception { mvc.perform(post("/api/core/users/{id}/email", UNVERIFIED_USER_ID) .param("code", changeEmailCode) - .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, tokens.get(UNVERIFIED_USER_ID)) + .header(HttpHeaders.AUTHORIZATION, tokens.get(UNVERIFIED_USER_ID)) .header("contentType", MediaType.APPLICATION_FORM_URLENCODED)) .andExpect(status().is(200)) .andExpect(header().string(LecUtils.TOKEN_RESPONSE_HEADER_NAME, containsString("."))) @@ -56,7 +57,7 @@ public void testChangeEmail() throws Exception { // Shouldn't be able to login with old token mvc.perform(post("/api/core/users/{id}/email", UNVERIFIED_USER_ID) .param("code", changeEmailCode) - .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, tokens.get(UNVERIFIED_USER_ID)) + .header(HttpHeaders.AUTHORIZATION, tokens.get(UNVERIFIED_USER_ID)) .header("contentType", MediaType.APPLICATION_FORM_URLENCODED)) .andExpect(status().is(401)); } @@ -70,7 +71,7 @@ public void testChangeEmailWrongCode() throws Exception { // Blank token mvc.perform(post("/api/core/users/{id}/email", UNVERIFIED_USER_ID) .param("code", "") - .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, tokens.get(UNVERIFIED_USER_ID)) + .header(HttpHeaders.AUTHORIZATION, tokens.get(UNVERIFIED_USER_ID)) .header("contentType", MediaType.APPLICATION_FORM_URLENCODED)) .andExpect(status().is(422)); @@ -82,7 +83,7 @@ public void testChangeEmailWrongCode() throws Exception { mvc.perform(post("/api/core/users/{id}/email", UNVERIFIED_USER_ID) .param("code", code) - .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, tokens.get(UNVERIFIED_USER_ID)) + .header(HttpHeaders.AUTHORIZATION, tokens.get(UNVERIFIED_USER_ID)) .header("contentType", MediaType.APPLICATION_FORM_URLENCODED)) .andExpect(status().is(401)); @@ -94,7 +95,7 @@ public void testChangeEmailWrongCode() throws Exception { mvc.perform(post("/api/core/users/{id}/email", UNVERIFIED_USER_ID) .param("code", code) - .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, tokens.get(UNVERIFIED_USER_ID)) + .header(HttpHeaders.AUTHORIZATION, tokens.get(UNVERIFIED_USER_ID)) .header("contentType", MediaType.APPLICATION_FORM_URLENCODED)) .andExpect(status().is(403)); @@ -106,7 +107,7 @@ public void testChangeEmailWrongCode() throws Exception { mvc.perform(post("/api/core/users/{id}/email", UNVERIFIED_USER_ID) .param("code", code) - .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, tokens.get(UNVERIFIED_USER_ID)) + .header(HttpHeaders.AUTHORIZATION, tokens.get(UNVERIFIED_USER_ID)) .header("contentType", MediaType.APPLICATION_FORM_URLENCODED)) .andExpect(status().is(403)); } @@ -129,7 +130,7 @@ public void testChangeEmailObsoleteCode() throws Exception { // now ready to test! mvc.perform(post("/api/core/users/{id}/email", UNVERIFIED_USER_ID) .param("code", changeEmailCode) - .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, authToken) + .header(HttpHeaders.AUTHORIZATION, authToken) .header("contentType", MediaType.APPLICATION_FORM_URLENCODED)) .andExpect(status().is(401)); } @@ -143,7 +144,7 @@ public void testChangeEmailWithoutAnyRequest() throws Exception { mvc.perform(post("/api/core/users/{id}/email", USER_ID) .param("code", changeEmailCode) - .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, tokens.get(USER_ID)) + .header(HttpHeaders.AUTHORIZATION, tokens.get(USER_ID)) .header("contentType", MediaType.APPLICATION_FORM_URLENCODED)) .andExpect(status().is(422)); } @@ -162,7 +163,7 @@ public void testChangeEmailNonUniqueEmail() throws Exception { mvc.perform(post("/api/core/users/{id}/email", UNVERIFIED_USER_ID) .param("code", changeEmailCode) - .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, tokens.get(UNVERIFIED_USER_ID)) + .header(HttpHeaders.AUTHORIZATION, tokens.get(UNVERIFIED_USER_ID)) .header("contentType", MediaType.APPLICATION_FORM_URLENCODED)) .andExpect(status().is(422)); } diff --git a/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/ChangePasswordMvcTests.java b/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/ChangePasswordMvcTests.java index 2a1bea99..818e4d26 100644 --- a/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/ChangePasswordMvcTests.java +++ b/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/ChangePasswordMvcTests.java @@ -9,6 +9,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; import org.junit.Test; +import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; import org.springframework.test.context.jdbc.Sql; @@ -37,7 +38,7 @@ private ChangePasswordForm changePasswordForm(String oldPassword) { public void testChangePassword() throws Exception { mvc.perform(post("/api/core/users/{id}/password", UNVERIFIED_USER_ID) - .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, tokens.get(UNVERIFIED_USER_ID)) + .header(HttpHeaders.AUTHORIZATION, tokens.get(UNVERIFIED_USER_ID)) .contentType(MediaType.APPLICATION_JSON) .content(LecUtils.toJson(changePasswordForm(USER_PASSWORD)))) .andExpect(status().is(204)) @@ -54,7 +55,7 @@ public void testChangePassword() throws Exception { public void testAdminChangePasswordAnotherUser() throws Exception { mvc.perform(post("/api/core/users/{id}/password", UNVERIFIED_USER_ID) - .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, tokens.get(ADMIN_ID)) + .header(HttpHeaders.AUTHORIZATION, tokens.get(ADMIN_ID)) .contentType(MediaType.APPLICATION_JSON) .content(LecUtils.toJson(changePasswordForm(ADMIN_PASSWORD)))) .andExpect(status().is(204)) @@ -71,7 +72,7 @@ public void testAdminChangePasswordAnotherUser() throws Exception { public void testChangePasswordUnknownId() throws Exception { mvc.perform(post("/api/core/users/99/password") - .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, tokens.get(ADMIN_ID)) + .header(HttpHeaders.AUTHORIZATION, tokens.get(ADMIN_ID)) .contentType(MediaType.APPLICATION_JSON) .content(LecUtils.toJson(changePasswordForm(ADMIN_PASSWORD)))) .andExpect(status().is(404)); @@ -84,7 +85,7 @@ public void testChangePasswordUnknownId() throws Exception { public void testChangePasswordAnotherUser() throws Exception { mvc.perform(post("/api/core/users/{id}/password", UNVERIFIED_USER_ID) - .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, tokens.get(USER_ID)) + .header(HttpHeaders.AUTHORIZATION, tokens.get(USER_ID)) .contentType(MediaType.APPLICATION_JSON) .content(LecUtils.toJson(changePasswordForm(USER_PASSWORD)))) .andExpect(status().is(403)); @@ -100,7 +101,7 @@ public void testChangePasswordAnotherUser() throws Exception { public void testBadAdminChangePasswordAnotherUser() throws Exception { mvc.perform(post("/api/core/users/{id}/password", UNVERIFIED_USER_ID) - .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, tokens.get(UNVERIFIED_ADMIN_ID)) + .header(HttpHeaders.AUTHORIZATION, tokens.get(UNVERIFIED_ADMIN_ID)) .contentType(MediaType.APPLICATION_JSON) .content(LecUtils.toJson(changePasswordForm(ADMIN_PASSWORD)))) .andExpect(status().is(403)); @@ -114,7 +115,7 @@ public void testChangePasswordInvalidData() throws Exception { // All fields null mvc.perform(post("/api/core/users/{id}/password", UNVERIFIED_USER_ID) - .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, tokens.get(UNVERIFIED_USER_ID)) + .header(HttpHeaders.AUTHORIZATION, tokens.get(UNVERIFIED_USER_ID)) .contentType(MediaType.APPLICATION_JSON) .content(LecUtils.toJson(new ChangePasswordForm()))) .andExpect(status().is(422)) @@ -131,7 +132,7 @@ public void testChangePasswordInvalidData() throws Exception { form.setRetypePassword("short"); mvc.perform(post("/api/core/users/{id}/password", UNVERIFIED_USER_ID) - .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, tokens.get(UNVERIFIED_USER_ID)) + .header(HttpHeaders.AUTHORIZATION, tokens.get(UNVERIFIED_USER_ID)) .contentType(MediaType.APPLICATION_JSON) .content(LecUtils.toJson(form))) .andExpect(status().is(422)) @@ -146,7 +147,7 @@ public void testChangePasswordInvalidData() throws Exception { form.setRetypePassword("different-retype-password"); mvc.perform(post("/api/core/users/{id}/password", UNVERIFIED_USER_ID) - .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, tokens.get(UNVERIFIED_USER_ID)) + .header(HttpHeaders.AUTHORIZATION, tokens.get(UNVERIFIED_USER_ID)) .contentType(MediaType.APPLICATION_JSON) .content(LecUtils.toJson(form))) .andExpect(status().is(422)) diff --git a/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/FetchNewTokenMvcTests.java b/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/FetchNewTokenMvcTests.java index a5b8bb69..862801f7 100644 --- a/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/FetchNewTokenMvcTests.java +++ b/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/FetchNewTokenMvcTests.java @@ -7,6 +7,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; import org.junit.Test; +import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; import org.springframework.test.web.servlet.MvcResult; @@ -31,7 +32,7 @@ public void setToken(String token) { public void testFetchNewToken() throws Exception { MvcResult result = mvc.perform(post("/api/core/fetch-new-auth-token") - .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, tokens.get(UNVERIFIED_USER_ID)) + .header(HttpHeaders.AUTHORIZATION, tokens.get(UNVERIFIED_USER_ID)) .header("contentType", MediaType.APPLICATION_FORM_URLENCODED)) .andExpect(status().is(200)) .andExpect(jsonPath("$.token").value(containsString("."))) @@ -45,7 +46,7 @@ public void testFetchNewToken() throws Exception { public void testFetchNewTokenExpiration() throws Exception { MvcResult result = mvc.perform(post("/api/core/fetch-new-auth-token") - .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, tokens.get(UNVERIFIED_USER_ID)) + .header(HttpHeaders.AUTHORIZATION, tokens.get(UNVERIFIED_USER_ID)) .param("expirationMillis", "1000") .header("contentType", MediaType.APPLICATION_FORM_URLENCODED)) .andExpect(status().is(200)) @@ -56,7 +57,7 @@ public void testFetchNewTokenExpiration() throws Exception { Thread.sleep(1001L); mvc.perform(get("/api/core/context") - .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, + .header(HttpHeaders.AUTHORIZATION, LecUtils.TOKEN_PREFIX + response.getToken())) .andExpect(status().is(401)); @@ -66,7 +67,7 @@ public void testFetchNewTokenExpiration() throws Exception { public void testFetchNewTokenByAdminForAnotherUser() throws Exception { MvcResult result = mvc.perform(post("/api/core/fetch-new-auth-token") - .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, tokens.get(ADMIN_ID)) + .header(HttpHeaders.AUTHORIZATION, tokens.get(ADMIN_ID)) .param("username", UNVERIFIED_USER_EMAIL) .header("contentType", MediaType.APPLICATION_FORM_URLENCODED)) .andExpect(status().is(200)) @@ -80,7 +81,7 @@ public void testFetchNewTokenByAdminForAnotherUser() throws Exception { public void testFetchNewTokenByNonAdminForAnotherUser() throws Exception { mvc.perform(post("/api/core/fetch-new-auth-token") - .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, tokens.get(UNVERIFIED_USER_ID)) + .header(HttpHeaders.AUTHORIZATION, tokens.get(UNVERIFIED_USER_ID)) .param("username", ADMIN_EMAIL) .header("contentType", MediaType.APPLICATION_FORM_URLENCODED)) .andExpect(status().is(403)); diff --git a/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/FetchUserMvcTests.java b/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/FetchUserMvcTests.java index 14b09cf8..494586e8 100644 --- a/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/FetchUserMvcTests.java +++ b/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/FetchUserMvcTests.java @@ -6,6 +6,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; import org.junit.Test; +import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; import org.springframework.test.context.jdbc.Sql; @@ -31,7 +32,7 @@ public void testFetchUserByIdLoggedIn() throws Exception { // Same user logged in mvc.perform(get("/api/core/users/{id}", ADMIN_ID) - .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, tokens.get(ADMIN_ID))) + .header(HttpHeaders.AUTHORIZATION, tokens.get(ADMIN_ID))) .andExpect(status().is(200)) .andExpect(jsonPath("$.id").value(ADMIN_ID)) .andExpect(jsonPath("$.email").value(ADMIN_EMAIL)) @@ -41,14 +42,14 @@ public void testFetchUserByIdLoggedIn() throws Exception { // Another user logged in mvc.perform(get("/api/core/users/{id}", ADMIN_ID) - .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, tokens.get(UNVERIFIED_USER_ID))) + .header(HttpHeaders.AUTHORIZATION, tokens.get(UNVERIFIED_USER_ID))) .andExpect(status().is(200)) .andExpect(jsonPath("$.id").value(ADMIN_ID)) .andExpect(jsonPath("$.email").doesNotExist()); // Admin user logged in - fetching another user mvc.perform(get("/api/core/users/{id}", UNVERIFIED_USER_ID) - .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, tokens.get(ADMIN_ID))) + .header(HttpHeaders.AUTHORIZATION, tokens.get(ADMIN_ID))) .andExpect(status().is(200)) .andExpect(jsonPath("$.id").value(UNVERIFIED_USER_ID)) .andExpect(jsonPath("$.email").value(UNVERIFIED_USER_EMAIL)); diff --git a/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/LoginMvcTests.java b/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/LoginMvcTests.java index 87d4f0fe..0e25146d 100644 --- a/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/LoginMvcTests.java +++ b/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/LoginMvcTests.java @@ -9,6 +9,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; import org.junit.Test; +import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; import org.springframework.test.context.jdbc.Sql; import org.springframework.test.web.servlet.MvcResult; @@ -58,7 +59,7 @@ public void testLoginTokenExpiry() throws Exception { // but, does expire after 500ms Thread.sleep(501L); mvc.perform(get("/api/core/ping") - .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, token)) + .header(HttpHeaders.AUTHORIZATION, token)) .andExpect(status().is(401)); } @@ -75,7 +76,7 @@ public void testObsoleteToken() throws Exception { userRepository.save(user); mvc.perform(get("/api/core/ping") - .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, tokens.get(ADMIN_ID))) + .header(HttpHeaders.AUTHORIZATION, tokens.get(ADMIN_ID))) .andExpect(status().is(401)); } @@ -103,7 +104,7 @@ public void testLoginBlankPassword() throws Exception { public void testTokenLogin() throws Exception { mvc.perform(get("/api/core/context") - .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, tokens.get(ADMIN_ID))) + .header(HttpHeaders.AUTHORIZATION, tokens.get(ADMIN_ID))) .andExpect(status().is(200)) .andExpect(jsonPath("$.user.id").value(ADMIN_ID)); } @@ -112,7 +113,7 @@ public void testTokenLogin() throws Exception { public void testTokenLoginWrongToken() throws Exception { mvc.perform(get("/api/core/context") - .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, "Bearer a-wrong-token")) + .header(HttpHeaders.AUTHORIZATION, "Bearer a-wrong-token")) .andExpect(status().is(401)); } diff --git a/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/RequestEmailChangeMvcTests.java b/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/RequestEmailChangeMvcTests.java index 75ada58d..01fc8694 100644 --- a/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/RequestEmailChangeMvcTests.java +++ b/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/RequestEmailChangeMvcTests.java @@ -11,6 +11,7 @@ import org.junit.Assert; import org.junit.Test; +import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; import com.fasterxml.jackson.core.JsonProcessingException; @@ -35,7 +36,7 @@ public void testRequestEmailChange() throws Exception { mvc.perform(post("/api/core/users/{id}/email-change-request", UNVERIFIED_USER_ID) .contentType(MediaType.APPLICATION_JSON) - .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, tokens.get(UNVERIFIED_USER_ID)) + .header(HttpHeaders.AUTHORIZATION, tokens.get(UNVERIFIED_USER_ID)) .content(LecUtils.toJson(form()))) .andExpect(status().is(204)); @@ -54,7 +55,7 @@ public void testGoodAdminRequestEmailChange() throws Exception { mvc.perform(post("/api/core/users/{id}/email-change-request", UNVERIFIED_USER_ID) .contentType(MediaType.APPLICATION_JSON) - .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, tokens.get(ADMIN_ID)) + .header(HttpHeaders.AUTHORIZATION, tokens.get(ADMIN_ID)) .content(LecUtils.toJson(form()))) .andExpect(status().is(204)); @@ -70,7 +71,7 @@ public void testRequestEmailChangeUnknownUser() throws Exception { mvc.perform(post("/api/core/users/99/email-change-request") .contentType(MediaType.APPLICATION_JSON) - .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, tokens.get(ADMIN_ID)) + .header(HttpHeaders.AUTHORIZATION, tokens.get(ADMIN_ID)) .content(LecUtils.toJson(form()))) .andExpect(status().is(404)); @@ -86,7 +87,7 @@ public void testNonAdminRequestEmailChangeAnotherUser() throws Exception { mvc.perform(post("/api/core/users/{id}/email-change-request", ADMIN_ID) .contentType(MediaType.APPLICATION_JSON) - .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, tokens.get(USER_ID)) + .header(HttpHeaders.AUTHORIZATION, tokens.get(USER_ID)) .content(LecUtils.toJson(form()))) .andExpect(status().is(403)); @@ -105,7 +106,7 @@ public void testBadAdminRequestEmailChangeAnotherUser() throws Exception { mvc.perform(post("/api/core/users/{id}/email-change-request", ADMIN_ID) .contentType(MediaType.APPLICATION_JSON) - .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, tokens.get(UNVERIFIED_ADMIN_ID)) + .header(HttpHeaders.AUTHORIZATION, tokens.get(UNVERIFIED_ADMIN_ID)) .content(LecUtils.toJson(form()))) .andExpect(status().is(403)); @@ -123,7 +124,7 @@ public void tryingWithInvalidData() throws JsonProcessingException, Exception { // try with null newEmail and password mvc.perform(post("/api/core/users/{id}/email-change-request", UNVERIFIED_USER_ID) .contentType(MediaType.APPLICATION_JSON) - .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, tokens.get(UNVERIFIED_USER_ID)) + .header(HttpHeaders.AUTHORIZATION, tokens.get(UNVERIFIED_USER_ID)) .content(LecUtils.toJson(new User()))) .andExpect(status().is(422)) .andExpect(jsonPath("$.errors[*].field").value(hasSize(2))) @@ -138,7 +139,7 @@ public void tryingWithInvalidData() throws JsonProcessingException, Exception { // try with blank newEmail and password mvc.perform(post("/api/core/users/{id}/email-change-request", UNVERIFIED_USER_ID) .contentType(MediaType.APPLICATION_JSON) - .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, tokens.get(UNVERIFIED_USER_ID)) + .header(HttpHeaders.AUTHORIZATION, tokens.get(UNVERIFIED_USER_ID)) .content(LecUtils.toJson(updatedUser))) .andExpect(status().is(422)) .andExpect(jsonPath("$.errors[*].field").value(hasSize(4))) @@ -151,7 +152,7 @@ public void tryingWithInvalidData() throws JsonProcessingException, Exception { updatedUser.setNewEmail("an-invalid-email"); mvc.perform(post("/api/core/users/{id}/email-change-request", UNVERIFIED_USER_ID) .contentType(MediaType.APPLICATION_JSON) - .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, tokens.get(UNVERIFIED_USER_ID)) + .header(HttpHeaders.AUTHORIZATION, tokens.get(UNVERIFIED_USER_ID)) .content(LecUtils.toJson(updatedUser))) .andExpect(status().is(422)) .andExpect(jsonPath("$.errors[*].field").value(hasSize(1))) @@ -162,7 +163,7 @@ public void tryingWithInvalidData() throws JsonProcessingException, Exception { updatedUser.setPassword("wrong-password"); mvc.perform(post("/api/core/users/{id}/email-change-request", UNVERIFIED_USER_ID) .contentType(MediaType.APPLICATION_JSON) - .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, tokens.get(UNVERIFIED_USER_ID)) + .header(HttpHeaders.AUTHORIZATION, tokens.get(UNVERIFIED_USER_ID)) .content(LecUtils.toJson(updatedUser))) .andExpect(status().is(422)) .andExpect(jsonPath("$.errors[*].field").value(hasSize(1))) @@ -173,7 +174,7 @@ public void tryingWithInvalidData() throws JsonProcessingException, Exception { updatedUser.setPassword(null); mvc.perform(post("/api/core/users/{id}/email-change-request", UNVERIFIED_USER_ID) .contentType(MediaType.APPLICATION_JSON) - .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, tokens.get(UNVERIFIED_USER_ID)) + .header(HttpHeaders.AUTHORIZATION, tokens.get(UNVERIFIED_USER_ID)) .content(LecUtils.toJson(updatedUser))) .andExpect(status().is(422)) .andExpect(jsonPath("$.errors[*].field").value(hasSize(1))) @@ -184,7 +185,7 @@ public void tryingWithInvalidData() throws JsonProcessingException, Exception { updatedUser.setNewEmail(ADMIN_EMAIL);; mvc.perform(post("/api/core/users/{id}/email-change-request", UNVERIFIED_USER_ID) .contentType(MediaType.APPLICATION_JSON) - .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, tokens.get(UNVERIFIED_USER_ID)) + .header(HttpHeaders.AUTHORIZATION, tokens.get(UNVERIFIED_USER_ID)) .content(LecUtils.toJson(updatedUser))) .andExpect(status().is(422)) .andExpect(jsonPath("$.errors[*].field").value(hasSize(1))) diff --git a/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/ResendVerificationMailMvcTests.java b/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/ResendVerificationMailMvcTests.java index e8b824fd..2afed92f 100644 --- a/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/ResendVerificationMailMvcTests.java +++ b/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/ResendVerificationMailMvcTests.java @@ -7,6 +7,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; import org.junit.Test; +import org.springframework.http.HttpHeaders; import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; @@ -16,7 +17,7 @@ public class ResendVerificationMailMvcTests extends AbstractMvcTests { public void testResendVerificationMail() throws Exception { mvc.perform(post("/api/core/users/{id}/resend-verification-mail", UNVERIFIED_USER_ID) - .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, tokens.get(UNVERIFIED_USER_ID))) + .header(HttpHeaders.AUTHORIZATION, tokens.get(UNVERIFIED_USER_ID))) .andExpect(status().is(204)); verify(mailSender).send(any()); @@ -26,7 +27,7 @@ public void testResendVerificationMail() throws Exception { public void testAdminResendVerificationMailOtherUser() throws Exception { mvc.perform(post("/api/core/users/{id}/resend-verification-mail", UNVERIFIED_USER_ID) - .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, tokens.get(ADMIN_ID))) + .header(HttpHeaders.AUTHORIZATION, tokens.get(ADMIN_ID))) .andExpect(status().is(204)); } @@ -34,11 +35,11 @@ public void testAdminResendVerificationMailOtherUser() throws Exception { public void testBadAdminResendVerificationMailOtherUser() throws Exception { mvc.perform(post("/api/core/users/{id}/resend-verification-mail", UNVERIFIED_USER_ID) - .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, tokens.get(UNVERIFIED_ADMIN_ID))) + .header(HttpHeaders.AUTHORIZATION, tokens.get(UNVERIFIED_ADMIN_ID))) .andExpect(status().is(403)); mvc.perform(post("/api/core/users/{id}/resend-verification-mail", UNVERIFIED_USER_ID) - .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, tokens.get(BLOCKED_ADMIN_ID))) + .header(HttpHeaders.AUTHORIZATION, tokens.get(BLOCKED_ADMIN_ID))) .andExpect(status().is(403)); verify(mailSender, never()).send(any()); @@ -57,7 +58,7 @@ public void testResendVerificationMailUnauthenticated() throws Exception { public void testResendVerificationMailAlreadyVerified() throws Exception { mvc.perform(post("/api/core/users/{id}/resend-verification-mail", USER_ID) - .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, tokens.get(USER_ID))) + .header(HttpHeaders.AUTHORIZATION, tokens.get(USER_ID))) .andExpect(status().is(422)); verify(mailSender, never()).send(any()); @@ -67,7 +68,7 @@ public void testResendVerificationMailAlreadyVerified() throws Exception { public void testResendVerificationMailOtherUser() throws Exception { mvc.perform(post("/api/core/users/{id}/resend-verification-mail", UNVERIFIED_USER_ID) - .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, tokens.get(USER_ID))) + .header(HttpHeaders.AUTHORIZATION, tokens.get(USER_ID))) .andExpect(status().is(403)); verify(mailSender, never()).send(any()); @@ -77,7 +78,7 @@ public void testResendVerificationMailOtherUser() throws Exception { public void testResendVerificationMailNonExistingUser() throws Exception { mvc.perform(post("/api/core/users/99/resend-verification-mail") - .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, tokens.get(ADMIN_ID))) + .header(HttpHeaders.AUTHORIZATION, tokens.get(ADMIN_ID))) .andExpect(status().is(404)); verify(mailSender, never()).send(any()); diff --git a/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/UpdateUserMvcTests.java b/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/UpdateUserMvcTests.java index 5038a62e..cbb53a49 100644 --- a/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/UpdateUserMvcTests.java +++ b/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/UpdateUserMvcTests.java @@ -13,6 +13,7 @@ import org.junit.Test; import org.springframework.beans.factory.annotation.Value; import org.springframework.core.io.Resource; +import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; import org.springframework.test.context.jdbc.Sql; @@ -62,7 +63,7 @@ public void testUpdateSelf() throws Exception { mvc.perform(patch("/api/core/users/{id}", UNVERIFIED_USER_ID) .contentType(MediaType.APPLICATION_JSON) - .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, tokens.get(UNVERIFIED_USER_ID)) + .header(HttpHeaders.AUTHORIZATION, tokens.get(UNVERIFIED_USER_ID)) .content(userPatch)) .andExpect(status().is(200)) .andExpect(header().string(LecUtils.TOKEN_RESPONSE_HEADER_NAME, containsString("."))) @@ -82,7 +83,7 @@ public void testUpdateSelf() throws Exception { // Version mismatch mvc.perform(patch("/api/core/users/{id}", UNVERIFIED_USER_ID) .contentType(MediaType.APPLICATION_JSON) - .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, tokens.get(UNVERIFIED_USER_ID)) + .header(HttpHeaders.AUTHORIZATION, tokens.get(UNVERIFIED_USER_ID)) .content(userPatch)) .andExpect(status().is(409)); } @@ -99,7 +100,7 @@ public void testGoodAdminCanUpdateOther() throws Exception { mvc.perform(patch("/api/core/users/{id}", UNVERIFIED_USER_ID) .contentType(MediaType.APPLICATION_JSON) - .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, tokens.get(ADMIN_ID)) + .header(HttpHeaders.AUTHORIZATION, tokens.get(ADMIN_ID)) .content(userPatch)) .andExpect(status().is(200)) .andExpect(header().string(LecUtils.TOKEN_RESPONSE_HEADER_NAME, containsString("."))) @@ -125,7 +126,7 @@ public void testUpdateUnknownId() throws Exception { mvc.perform(patch("/api/core/users/{id}", 99) .contentType(MediaType.APPLICATION_JSON) - .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, tokens.get(ADMIN_ID)) + .header(HttpHeaders.AUTHORIZATION, tokens.get(ADMIN_ID)) .content(userPatch)) .andExpect(status().is(404)); } @@ -139,7 +140,7 @@ public void testUpdateAnotherUser() throws Exception { mvc.perform(patch("/api/core/users/{id}", ADMIN_ID) .contentType(MediaType.APPLICATION_JSON) - .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, tokens.get(UNVERIFIED_USER_ID)) + .header(HttpHeaders.AUTHORIZATION, tokens.get(UNVERIFIED_USER_ID)) .content(userPatch)) .andExpect(status().is(403)); } @@ -153,13 +154,13 @@ public void testBadAdminUpdateAnotherUser() throws Exception { mvc.perform(patch("/api/core/users/{id}", UNVERIFIED_USER_ID) .contentType(MediaType.APPLICATION_JSON) - .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, tokens.get(UNVERIFIED_ADMIN_ID)) + .header(HttpHeaders.AUTHORIZATION, tokens.get(UNVERIFIED_ADMIN_ID)) .content(userPatch)) .andExpect(status().is(403)); mvc.perform(patch("/api/core/users/{id}", UNVERIFIED_USER_ID) .contentType(MediaType.APPLICATION_JSON) - .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, tokens.get(BLOCKED_ADMIN_ID)) + .header(HttpHeaders.AUTHORIZATION, tokens.get(BLOCKED_ADMIN_ID)) .content(userPatch)) .andExpect(status().is(403)); } @@ -173,7 +174,7 @@ public void goodAdminCanNotUpdateSelfRoles() throws Exception { mvc.perform(patch("/api/core/users/{id}", ADMIN_ID) .contentType(MediaType.APPLICATION_JSON) - .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, tokens.get(ADMIN_ID)) + .header(HttpHeaders.AUTHORIZATION, tokens.get(ADMIN_ID)) .content(userPatchAdminRole)) .andExpect(status().is(200)) .andExpect(jsonPath("$.tag.name").value(UPDATED_NAME)) @@ -191,14 +192,14 @@ public void testUpdateUserInvalidNewName() throws Exception { // Null name mvc.perform(patch("/api/core/users/{id}", UNVERIFIED_USER_ID) .contentType(MediaType.APPLICATION_JSON) - .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, tokens.get(UNVERIFIED_USER_ID)) + .header(HttpHeaders.AUTHORIZATION, tokens.get(UNVERIFIED_USER_ID)) .content(userPatchNullName)) .andExpect(status().is(422)); // Too long name mvc.perform(patch("/api/core/users/{id}", UNVERIFIED_USER_ID) .contentType(MediaType.APPLICATION_JSON) - .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, tokens.get(UNVERIFIED_USER_ID)) + .header(HttpHeaders.AUTHORIZATION, tokens.get(UNVERIFIED_USER_ID)) .content(userPatchLongName)) .andExpect(status().is(422)); } diff --git a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/ChangeEmailTests.java b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/ChangeEmailTests.java index 1ffeaba6..63def41e 100644 --- a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/ChangeEmailTests.java +++ b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/ChangeEmailTests.java @@ -14,6 +14,7 @@ import org.junit.Before; import org.junit.Test; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.test.web.reactive.server.WebTestClient.ResponseSpec; @@ -113,7 +114,7 @@ public void testChangeEmailObsoleteCode() throws Exception { String authToken = testUtils.login(UNVERIFIED_USER_EMAIL, USER_PASSWORD); CLIENT.post().uri(BASE_URI + "/users/{id}/email", UNVERIFIED_USER_ID) - .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, authToken) + .header(HttpHeaders.AUTHORIZATION, authToken) .body(fromFormData("code", changeEmailCode)) .exchange() .expectStatus().isUnauthorized(); @@ -127,7 +128,7 @@ public void testChangeEmailObsoleteCode() throws Exception { public void testChangeEmailWithoutAnyRequest() throws Exception { CLIENT.post().uri(BASE_URI + "/users/{id}/email", USER_ID) - .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, TOKENS.get(USER_ID)) + .header(HttpHeaders.AUTHORIZATION, TOKENS.get(USER_ID)) .body(fromFormData("code", changeEmailCode)) .exchange() .expectStatus().isEqualTo(HttpStatus.UNPROCESSABLE_ENTITY); @@ -153,7 +154,7 @@ public void testChangeEmailNonUniqueEmail() throws Exception { private ResponseSpec changeEmailResponse(String code) { return CLIENT.post().uri(BASE_URI + "/users/{id}/email", UNVERIFIED_USER_ID) - .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, TOKENS.get(UNVERIFIED_USER_ID)) + .header(HttpHeaders.AUTHORIZATION, TOKENS.get(UNVERIFIED_USER_ID)) .body(fromFormData("code", code)) .exchange(); } diff --git a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/ChangePasswordTests.java b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/ChangePasswordTests.java index 3e74750b..9a473140 100644 --- a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/ChangePasswordTests.java +++ b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/ChangePasswordTests.java @@ -13,6 +13,7 @@ import org.bson.types.ObjectId; import org.junit.Test; +import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; @@ -43,7 +44,7 @@ private ChangePasswordForm changePasswordForm(String oldPassword) { public void testChangePassword() throws Exception { CLIENT.post().uri(BASE_URI + "/users/{id}/password", UNVERIFIED_USER_ID) - .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, TOKENS.get(UNVERIFIED_USER_ID)) + .header(HttpHeaders.AUTHORIZATION, TOKENS.get(UNVERIFIED_USER_ID)) .contentType(MediaType.APPLICATION_JSON) .body(Mono.just(changePasswordForm(USER_PASSWORD)), ChangePasswordForm.class) .exchange() @@ -62,7 +63,7 @@ public void testChangePassword() throws Exception { public void testAdminChangePasswordAnotherUser() throws Exception { CLIENT.post().uri(BASE_URI + "/users/{id}/password", UNVERIFIED_USER_ID) - .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, TOKENS.get(ADMIN_ID)) + .header(HttpHeaders.AUTHORIZATION, TOKENS.get(ADMIN_ID)) .contentType(MediaType.APPLICATION_JSON) .body(Mono.just(changePasswordForm(ADMIN_PASSWORD)), ChangePasswordForm.class) .exchange() @@ -80,7 +81,7 @@ public void testAdminChangePasswordAnotherUser() throws Exception { public void testChangePasswordUnknownId() throws Exception { CLIENT.post().uri(BASE_URI + "/users/{id}/password", ObjectId.get()) - .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, TOKENS.get(ADMIN_ID)) + .header(HttpHeaders.AUTHORIZATION, TOKENS.get(ADMIN_ID)) .contentType(MediaType.APPLICATION_JSON) .body(Mono.just(changePasswordForm(ADMIN_PASSWORD)), ChangePasswordForm.class) .exchange() @@ -95,7 +96,7 @@ public void testChangePasswordUnknownId() throws Exception { public void testChangePasswordAnotherUser() throws Exception { CLIENT.post().uri(BASE_URI + "/users/{id}/password", UNVERIFIED_USER_ID) - .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, TOKENS.get(USER_ID)) + .header(HttpHeaders.AUTHORIZATION, TOKENS.get(USER_ID)) .contentType(MediaType.APPLICATION_JSON) .body(Mono.just(changePasswordForm(USER_PASSWORD)), ChangePasswordForm.class) .exchange() @@ -114,7 +115,7 @@ public void testChangePasswordAnotherUser() throws Exception { public void testBadAdminChangePasswordAnotherUser() throws Exception { CLIENT.post().uri(BASE_URI + "/users/{id}/password", UNVERIFIED_USER_ID) - .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, TOKENS.get(UNVERIFIED_ADMIN_ID)) + .header(HttpHeaders.AUTHORIZATION, TOKENS.get(UNVERIFIED_ADMIN_ID)) .contentType(MediaType.APPLICATION_JSON) .body(Mono.just(changePasswordForm(ADMIN_PASSWORD)), ChangePasswordForm.class) .exchange() @@ -131,7 +132,7 @@ public void testChangePasswordInvalidData() throws Exception { //@formatter:off CLIENT.post().uri(BASE_URI + "/users/{id}/password", UNVERIFIED_USER_ID) - .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, TOKENS.get(ADMIN_ID)) + .header(HttpHeaders.AUTHORIZATION, TOKENS.get(ADMIN_ID)) .contentType(MediaType.APPLICATION_JSON) .body(Mono.just(new ChangePasswordForm()), ChangePasswordForm.class) .exchange() @@ -157,7 +158,7 @@ public void testChangePasswordInvalidData() throws Exception { //@formatter:off CLIENT.post().uri(BASE_URI + "/users/{id}/password", UNVERIFIED_USER_ID) - .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, TOKENS.get(ADMIN_ID)) + .header(HttpHeaders.AUTHORIZATION, TOKENS.get(ADMIN_ID)) .contentType(MediaType.APPLICATION_JSON) .body(Mono.just(form), ChangePasswordForm.class) .exchange() @@ -181,7 +182,7 @@ public void testChangePasswordInvalidData() throws Exception { //@formatter:off CLIENT.post().uri(BASE_URI + "/users/{id}/password", UNVERIFIED_USER_ID) - .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, TOKENS.get(ADMIN_ID)) + .header(HttpHeaders.AUTHORIZATION, TOKENS.get(ADMIN_ID)) .contentType(MediaType.APPLICATION_JSON) .body(Mono.just(form), ChangePasswordForm.class) .exchange() diff --git a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/FetchNewTokenTests.java b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/FetchNewTokenTests.java index 426f2553..f5a8ba90 100644 --- a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/FetchNewTokenTests.java +++ b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/FetchNewTokenTests.java @@ -11,6 +11,7 @@ import static org.springframework.web.reactive.function.BodyInserters.fromFormData; import org.junit.Test; +import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; import org.springframework.test.web.reactive.server.EntityExchangeResult; @@ -25,7 +26,7 @@ public void testFetchNewToken() throws Exception { CLIENT.post().uri(BASE_URI + "/fetch-new-auth-token") .contentType(MediaType.APPLICATION_FORM_URLENCODED) - .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, TOKENS.get(UNVERIFIED_USER_ID)) + .header(HttpHeaders.AUTHORIZATION, TOKENS.get(UNVERIFIED_USER_ID)) .exchange() .expectStatus().isOk() .expectBody(TestToken.class) @@ -38,7 +39,7 @@ public void testFetchNewTokenExpiration() throws Exception { CLIENT.post().uri(BASE_URI + "/fetch-new-auth-token") .contentType(MediaType.APPLICATION_FORM_URLENCODED) - .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, TOKENS.get(UNVERIFIED_USER_ID)) + .header(HttpHeaders.AUTHORIZATION, TOKENS.get(UNVERIFIED_USER_ID)) .body(fromFormData("expirationMillis", "1000")) .exchange() .expectStatus().isOk() @@ -56,7 +57,7 @@ public void testFetchNewTokenExpiration() throws Exception { CLIENT.get() .uri(BASE_URI + "/context") - .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, token.getToken()) + .header(HttpHeaders.AUTHORIZATION, token.getToken()) .exchange() .expectStatus().isUnauthorized(); }); @@ -67,7 +68,7 @@ public void testFetchNewTokenByAdminForAnotherUser() throws Exception { CLIENT.post().uri(BASE_URI + "/fetch-new-auth-token") .contentType(MediaType.APPLICATION_FORM_URLENCODED) - .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, TOKENS.get(ADMIN_ID)) + .header(HttpHeaders.AUTHORIZATION, TOKENS.get(ADMIN_ID)) .body(fromFormData("username", UNVERIFIED_USER_EMAIL)) .exchange() .expectStatus().isOk() @@ -81,7 +82,7 @@ public void testFetchNewTokenByNonAdminForAnotherUser() throws Exception { CLIENT.post().uri(BASE_URI + "/fetch-new-auth-token") .contentType(MediaType.APPLICATION_FORM_URLENCODED) - .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, TOKENS.get(UNVERIFIED_USER_ID)) + .header(HttpHeaders.AUTHORIZATION, TOKENS.get(UNVERIFIED_USER_ID)) .body(fromFormData("username", ADMIN_EMAIL)) .exchange() .expectStatus().isForbidden() diff --git a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/FetchUserTests.java b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/FetchUserTests.java index 98881a47..70e5bcfb 100644 --- a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/FetchUserTests.java +++ b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/FetchUserTests.java @@ -11,6 +11,7 @@ import org.bson.types.ObjectId; import org.junit.Test; +import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; @@ -37,7 +38,7 @@ public void testFetchUserByIdLoggedIn() throws Exception { // Same user logged in CLIENT.get().uri(BASE_URI + "/users/{id}", ADMIN_ID) - .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, TOKENS.get(ADMIN_ID)) + .header(HttpHeaders.AUTHORIZATION, TOKENS.get(ADMIN_ID)) .exchange() .expectStatus().isOk() .expectBody() @@ -49,7 +50,7 @@ public void testFetchUserByIdLoggedIn() throws Exception { // Another user logged in CLIENT.get().uri(BASE_URI + "/users/{id}", ADMIN_ID) - .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, TOKENS.get(UNVERIFIED_USER_ID)) + .header(HttpHeaders.AUTHORIZATION, TOKENS.get(UNVERIFIED_USER_ID)) .exchange() .expectStatus().isOk() .expectBody() @@ -58,7 +59,7 @@ public void testFetchUserByIdLoggedIn() throws Exception { // Admin user logged in - fetching another user CLIENT.get().uri(BASE_URI + "/users/{id}", UNVERIFIED_USER_ID) - .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, TOKENS.get(ADMIN_ID)) + .header(HttpHeaders.AUTHORIZATION, TOKENS.get(ADMIN_ID)) .exchange() .expectStatus().isOk() .expectBody() diff --git a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/LoginTests.java b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/LoginTests.java index 4472a153..15d5e6de 100644 --- a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/LoginTests.java +++ b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/LoginTests.java @@ -13,6 +13,7 @@ import static org.springframework.web.reactive.function.BodyInserters.fromFormData; import org.junit.Test; +import org.springframework.http.HttpHeaders; import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; import com.naturalprogrammer.spring.lemondemo.domain.User; @@ -53,7 +54,7 @@ public void testLoginTokenExpiry() throws Exception { CLIENT.get() .uri(BASE_URI + "/ping") - .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, token) + .header(HttpHeaders.AUTHORIZATION, token) .exchange() .expectStatus().isUnauthorized(); } @@ -68,7 +69,7 @@ public void testObsoleteToken() throws Exception { CLIENT.get() .uri(BASE_URI + "/ping") - .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, TOKENS.get(ADMIN_ID)) + .header(HttpHeaders.AUTHORIZATION, TOKENS.get(ADMIN_ID)) .exchange() .expectStatus().isUnauthorized(); } @@ -94,7 +95,7 @@ public void testLoginBlankPassword() throws Exception { public void testTokenLogin() { CLIENT.get().uri(BASE_URI + "/context") - .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, TOKENS.get(ADMIN_ID)) + .header(HttpHeaders.AUTHORIZATION, TOKENS.get(ADMIN_ID)) .exchange() .expectStatus().isOk() .expectBody() @@ -106,7 +107,7 @@ public void testTokenLogin() { public void testTokenLoginWrongToken() { CLIENT.get().uri(BASE_URI + "/context") - .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, "Bearer a-wrong-token") + .header(HttpHeaders.AUTHORIZATION, "Bearer a-wrong-token") .exchange() .expectStatus().isUnauthorized(); } diff --git a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/MyTestUtils.java b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/MyTestUtils.java index 54144ea2..7d2c400d 100644 --- a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/MyTestUtils.java +++ b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/MyTestUtils.java @@ -15,6 +15,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationContext; import org.springframework.data.mongodb.core.MongoTemplate; +import org.springframework.http.HttpHeaders; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.stereotype.Component; import org.springframework.test.web.reactive.server.WebTestClient; @@ -83,7 +84,7 @@ public ResponseSpec contextResponse(String token) { return CLIENT.get() .uri(BASE_URI + "/context") - .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, token) + .header(HttpHeaders.AUTHORIZATION, token) .exchange() .expectStatus().isOk(); } diff --git a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/RequestEmailChangeTests.java b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/RequestEmailChangeTests.java index 63277e8e..78f12e02 100644 --- a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/RequestEmailChangeTests.java +++ b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/RequestEmailChangeTests.java @@ -17,6 +17,7 @@ import org.bson.types.ObjectId; import org.junit.Assert; import org.junit.Test; +import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.test.web.reactive.server.WebTestClient.BodySpec; @@ -47,7 +48,7 @@ private TestEmailForm form() { public void testRequestEmailChange() { CLIENT.post().uri(BASE_URI + "/users/{id}/email-change-request", UNVERIFIED_USER_ID) - .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, TOKENS.get(UNVERIFIED_USER_ID)) + .header(HttpHeaders.AUTHORIZATION, TOKENS.get(UNVERIFIED_USER_ID)) .contentType(MediaType.APPLICATION_JSON) .body(Mono.just(form()), TestEmailForm.class) .exchange() @@ -68,7 +69,7 @@ public void testRequestEmailChange() { public void testGoodAdminRequestEmailChange() throws Exception { CLIENT.post().uri(BASE_URI + "/users/{id}/email-change-request", UNVERIFIED_USER_ID) - .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, TOKENS.get(ADMIN_ID)) + .header(HttpHeaders.AUTHORIZATION, TOKENS.get(ADMIN_ID)) .contentType(MediaType.APPLICATION_JSON) .body(Mono.just(form()), TestEmailForm.class) .exchange() @@ -86,7 +87,7 @@ public void testGoodAdminRequestEmailChange() throws Exception { public void testRequestEmailChangeUnknownUser() throws Exception { CLIENT.post().uri(BASE_URI + "/users/{id}/email-change-request", ObjectId.get()) - .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, TOKENS.get(ADMIN_ID)) + .header(HttpHeaders.AUTHORIZATION, TOKENS.get(ADMIN_ID)) .contentType(MediaType.APPLICATION_JSON) .body(Mono.just(form()), TestEmailForm.class) .exchange() @@ -104,7 +105,7 @@ public void testRequestEmailChangeUnknownUser() throws Exception { public void testNonAdminRequestEmailChangeAnotherUser() throws Exception { CLIENT.post().uri(BASE_URI + "/users/{id}/email-change-request", ADMIN_ID) - .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, TOKENS.get(USER_ID)) + .header(HttpHeaders.AUTHORIZATION, TOKENS.get(USER_ID)) .contentType(MediaType.APPLICATION_JSON) .body(Mono.just(form()), TestEmailForm.class) .exchange() @@ -123,7 +124,7 @@ public void testNonAdminRequestEmailChangeAnotherUser() throws Exception { public void testBadAdminRequestEmailChangeAnotherUser() throws Exception { CLIENT.post().uri(BASE_URI + "/users/{id}/email-change-request", ADMIN_ID) - .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, TOKENS.get(UNVERIFIED_ADMIN_ID)) + .header(HttpHeaders.AUTHORIZATION, TOKENS.get(UNVERIFIED_ADMIN_ID)) .contentType(MediaType.APPLICATION_JSON) .body(Mono.just(form()), TestEmailForm.class) .exchange() @@ -212,7 +213,7 @@ public void testRequestEmailChangeWithInvalidData() { //@formatter:off return CLIENT.post().uri(BASE_URI + "/users/{id}/email-change-request", UNVERIFIED_USER_ID) - .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, TOKENS.get(UNVERIFIED_USER_ID)) + .header(HttpHeaders.AUTHORIZATION, TOKENS.get(UNVERIFIED_USER_ID)) .contentType(MediaType.APPLICATION_JSON) .body(Mono.just(form), TestEmailForm.class) .exchange() diff --git a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/ResendVerificationMailTests.java b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/ResendVerificationMailTests.java index 126d4692..b1494761 100644 --- a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/ResendVerificationMailTests.java +++ b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/ResendVerificationMailTests.java @@ -14,6 +14,7 @@ import org.bson.types.ObjectId; import org.junit.Test; +import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.test.web.reactive.server.WebTestClient.ResponseSpec; @@ -96,7 +97,7 @@ public void testResendVerificationMailNonExistingUser() { private ResponseSpec resendVerificationMail(ObjectId userId, ObjectId loggedInId) { return CLIENT.post().uri(BASE_URI + "/users/{id}/resend-verification-mail", userId) - .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, TOKENS.get(loggedInId)) + .header(HttpHeaders.AUTHORIZATION, TOKENS.get(loggedInId)) .exchange(); } diff --git a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/UpdateUserTests.java b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/UpdateUserTests.java index 1eb05ba8..e3826da7 100644 --- a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/UpdateUserTests.java +++ b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/UpdateUserTests.java @@ -15,6 +15,7 @@ import org.junit.Test; import org.springframework.beans.factory.annotation.Value; import org.springframework.core.io.Resource; +import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.test.web.reactive.server.WebTestClient.ResponseSpec; @@ -193,7 +194,7 @@ private ResponseSpec updateUser(ObjectId userId, ObjectId loggedInId, Resource p return CLIENT.patch().uri(BASE_URI + "/users/{id}", userId) .contentType(MediaType.APPLICATION_JSON) - .header(LecUtils.TOKEN_REQUEST_HEADER_NAME, TOKENS.get(loggedInId)) + .header(HttpHeaders.AUTHORIZATION, TOKENS.get(loggedInId)) .body(BodyInserters.fromResource(patch)) .exchange(); diff --git a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/LemonProperties.java b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/LemonProperties.java index 714859cb..590a677e 100644 --- a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/LemonProperties.java +++ b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/LemonProperties.java @@ -5,6 +5,7 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.http.HttpHeaders; import org.springframework.validation.annotation.Validated; import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; @@ -196,7 +197,7 @@ public static class Cors { "Referer", "User-Agent", "x-requested-with", - LecUtils.TOKEN_REQUEST_HEADER_NAME}; + HttpHeaders.AUTHORIZATION}; /** * Response headers that you want to expose to the client JavaScript programmer, e.g. Lemon-Authorization. diff --git a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/util/LecUtils.java b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/util/LecUtils.java index 0f57054d..b04205d0 100644 --- a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/util/LecUtils.java +++ b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/util/LecUtils.java @@ -45,7 +45,6 @@ public class LecUtils { // JWT Token related public static final String TOKEN_PREFIX = "Bearer "; - public static final String TOKEN_REQUEST_HEADER_NAME = "Authorization"; public static final String TOKEN_RESPONSE_HEADER_NAME = "Lemon-Authorization"; public static ApplicationContext applicationContext; diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonTokenAuthenticationFilter.java b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonTokenAuthenticationFilter.java index 3c8cf63c..38ffe11f 100644 --- a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonTokenAuthenticationFilter.java +++ b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonTokenAuthenticationFilter.java @@ -9,6 +9,7 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.springframework.http.HttpHeaders; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContextHolder; @@ -37,7 +38,7 @@ public LemonTokenAuthenticationFilter(AuthenticationManager authenticationManage */ protected boolean tokenPresent(HttpServletRequest request) { - String header = request.getHeader(LecUtils.TOKEN_REQUEST_HEADER_NAME); + String header = request.getHeader(HttpHeaders.AUTHORIZATION); return header != null && header.startsWith(LecUtils.TOKEN_PREFIX); } @@ -51,7 +52,7 @@ protected void doFilterInternal(HttpServletRequest request, HttpServletResponse log.debug("Found a token"); - String token = request.getHeader(LecUtils.TOKEN_REQUEST_HEADER_NAME).substring(7); + String token = request.getHeader(HttpHeaders.AUTHORIZATION).substring(7); JwtAuthenticationToken authRequest = new JwtAuthenticationToken(token); try { From 40b34bc8879c98fcd4cfc9b3bee429c650fffb4d Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Mon, 23 Jul 2018 18:43:08 +0530 Subject: [PATCH 023/116] Fixed #19: Implemented lombok wherever needed --- .../spring/lemondemo/entities/User.java | 25 +-- .../spring/lemondemo/FetchUserMvcTests.java | 2 - .../ResendVerificationMailMvcTests.java | 2 - .../spring/lemondemo/domain/User.java | 8 - .../spring/lemondemo/AbstractTests.java | 2 +- .../spring/lemondemo/FetchNewTokenTests.java | 1 - .../spring/lemondemo/FetchUserTests.java | 2 - .../lemondemo/RequestEmailChangeTests.java | 1 - .../ResendVerificationMailTests.java | 2 - .../lemondemo/dto/TestResetPasswordForm.java | 4 - .../spring/lemondemo/dto/TestToken.java | 1 + .../spring/lemon/commons/LemonProperties.java | 165 +----------------- .../commons/domain/ChangePasswordForm.java | 39 +---- .../lemon/commons/mail/LemonMailData.java | 25 +-- .../spring/lemon/commons/util/LecUtils.java | 1 - .../lemon/exceptions/LemonFieldError.java | 1 - .../lemon/exceptions/MultiErrorException.java | 15 +- .../spring/lemon/domain/VersionedEntity.java | 12 +- .../spring/lemon/util/LemonUtils.java | 2 - 19 files changed, 34 insertions(+), 276 deletions(-) diff --git a/lemon-demo-jpa/src/main/java/com/naturalprogrammer/spring/lemondemo/entities/User.java b/lemon-demo-jpa/src/main/java/com/naturalprogrammer/spring/lemondemo/entities/User.java index dcbdc23d..b1875d78 100644 --- a/lemon-demo-jpa/src/main/java/com/naturalprogrammer/spring/lemondemo/entities/User.java +++ b/lemon-demo-jpa/src/main/java/com/naturalprogrammer/spring/lemondemo/entities/User.java @@ -12,8 +12,13 @@ import com.naturalprogrammer.spring.lemon.commons.util.UserUtils; import com.naturalprogrammer.spring.lemon.domain.AbstractUser; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + @Entity @Table(name="usr") +@Getter @Setter @NoArgsConstructor public class User extends AbstractUser { private static final long serialVersionUID = 2716710947175132319L; @@ -21,23 +26,13 @@ public class User extends AbstractUser { public static final int NAME_MIN = 1; public static final int NAME_MAX = 50; + @Getter @Setter public static class Tag implements Serializable { private static final long serialVersionUID = -2129078111926834670L; - private String name; - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } } - public User() {} - public User(String email, String password, String name) { this.email = email; this.password = password; @@ -57,12 +52,4 @@ public Tag toTag() { tag.setName(name); return tag; } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } } \ No newline at end of file diff --git a/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/FetchUserMvcTests.java b/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/FetchUserMvcTests.java index 494586e8..259a63ef 100644 --- a/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/FetchUserMvcTests.java +++ b/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/FetchUserMvcTests.java @@ -10,8 +10,6 @@ import org.springframework.http.MediaType; import org.springframework.test.context.jdbc.Sql; -import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; - @Sql({"/test-data/initialize.sql", "/test-data/finalize.sql"}) public class FetchUserMvcTests extends AbstractMvcTests { diff --git a/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/ResendVerificationMailMvcTests.java b/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/ResendVerificationMailMvcTests.java index 2afed92f..66a40a0e 100644 --- a/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/ResendVerificationMailMvcTests.java +++ b/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/ResendVerificationMailMvcTests.java @@ -9,8 +9,6 @@ import org.junit.Test; import org.springframework.http.HttpHeaders; -import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; - public class ResendVerificationMailMvcTests extends AbstractMvcTests { @Test diff --git a/lemon-demo-reactive/src/main/java/com/naturalprogrammer/spring/lemondemo/domain/User.java b/lemon-demo-reactive/src/main/java/com/naturalprogrammer/spring/lemondemo/domain/User.java index 14b6cd46..7bace97b 100644 --- a/lemon-demo-reactive/src/main/java/com/naturalprogrammer/spring/lemondemo/domain/User.java +++ b/lemon-demo-reactive/src/main/java/com/naturalprogrammer/spring/lemondemo/domain/User.java @@ -43,12 +43,4 @@ public Tag toTag() { tag.setName(name); return tag; } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } } diff --git a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/AbstractTests.java b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/AbstractTests.java index a83ee838..eec0e758 100644 --- a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/AbstractTests.java +++ b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/AbstractTests.java @@ -21,7 +21,7 @@ @RunWith(SpringRunner.class) @SpringBootTest({ - "logging.level.com.naturalprogrammer=DEBUG", // logging.level.root=ERROR does not work: https://stackoverflow.com/questions/49048298/springboottest-not-overriding-logging-level + "logging.level.com.naturalprogrammer=ERROR", // logging.level.root=ERROR does not work: https://stackoverflow.com/questions/49048298/springboottest-not-overriding-logging-level "logging.level.org.springframework=ERROR", "lemon.recaptcha.sitekey=", "spring.data.mongodb.database=lemontest" diff --git a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/FetchNewTokenTests.java b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/FetchNewTokenTests.java index f5a8ba90..84945f38 100644 --- a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/FetchNewTokenTests.java +++ b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/FetchNewTokenTests.java @@ -15,7 +15,6 @@ import org.springframework.http.MediaType; import org.springframework.test.web.reactive.server.EntityExchangeResult; -import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; import com.naturalprogrammer.spring.lemondemo.dto.TestToken; public class FetchNewTokenTests extends AbstractTests { diff --git a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/FetchUserTests.java b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/FetchUserTests.java index 70e5bcfb..d9cd4c9f 100644 --- a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/FetchUserTests.java +++ b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/FetchUserTests.java @@ -15,8 +15,6 @@ import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; -import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; - public class FetchUserTests extends AbstractTests { @Test diff --git a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/RequestEmailChangeTests.java b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/RequestEmailChangeTests.java index 78f12e02..f72a5ae4 100644 --- a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/RequestEmailChangeTests.java +++ b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/RequestEmailChangeTests.java @@ -23,7 +23,6 @@ import org.springframework.test.web.reactive.server.WebTestClient.BodySpec; import com.fasterxml.jackson.core.JsonProcessingException; -import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; import com.naturalprogrammer.spring.lemondemo.domain.User; import com.naturalprogrammer.spring.lemondemo.dto.TestEmailForm; import com.naturalprogrammer.spring.lemondemo.dto.TestErrorResponse; diff --git a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/ResendVerificationMailTests.java b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/ResendVerificationMailTests.java index b1494761..5633a3e0 100644 --- a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/ResendVerificationMailTests.java +++ b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/ResendVerificationMailTests.java @@ -18,8 +18,6 @@ import org.springframework.http.HttpStatus; import org.springframework.test.web.reactive.server.WebTestClient.ResponseSpec; -import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; - public class ResendVerificationMailTests extends AbstractTests { @Test diff --git a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/dto/TestResetPasswordForm.java b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/dto/TestResetPasswordForm.java index 086f76ba..9f8191c9 100644 --- a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/dto/TestResetPasswordForm.java +++ b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/dto/TestResetPasswordForm.java @@ -1,9 +1,5 @@ package com.naturalprogrammer.spring.lemondemo.dto; -import javax.validation.constraints.NotBlank; - -import com.naturalprogrammer.spring.lemon.commons.validation.Password; - import lombok.Getter; import lombok.Setter; diff --git a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/dto/TestToken.java b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/dto/TestToken.java index fced0b64..c537f60b 100644 --- a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/dto/TestToken.java +++ b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/dto/TestToken.java @@ -5,5 +5,6 @@ @Getter @Setter public class TestToken { + private String token; } diff --git a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/LemonProperties.java b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/LemonProperties.java index 590a677e..c4d7d23c 100644 --- a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/LemonProperties.java +++ b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/LemonProperties.java @@ -10,6 +10,9 @@ import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; +import lombok.Getter; +import lombok.Setter; + /** * Lemon Properties * @@ -17,6 +20,7 @@ */ @Validated @ConfigurationProperties(prefix="lemon") +@Getter @Setter public class LemonProperties { private static final Log log = LogFactory.getLog(LemonProperties.class); @@ -65,66 +69,6 @@ public LemonProperties() { private Jwt jwt; - /************************** - * Gettrer and setters - **************************/ - public Recaptcha getRecaptcha() { - return recaptcha; - } - - public void setRecaptcha(Recaptcha recaptcha) { - this.recaptcha = recaptcha; - } - - - public Cors getCors() { - return cors; - } - - public void setCors(Cors cors) { - this.cors = cors; - } - - public Admin getAdmin() { - return admin; - } - - public void setAdmin(Admin admin) { - this.admin = admin; - } - - public Map getShared() { - return shared; - } - - public void setShared(Map shared) { - this.shared = shared; - } - - public String getApplicationUrl() { - return applicationUrl; - } - - public void setApplicationUrl(String applicationUrl) { - this.applicationUrl = applicationUrl; - } - - public String getOauth2AuthenticationSuccessUrl() { - return oauth2AuthenticationSuccessUrl; - } - - public void setOauth2AuthenticationSuccessUrl(String oauth2AuthenticationSuccessUrl) { - this.oauth2AuthenticationSuccessUrl = oauth2AuthenticationSuccessUrl; - } - - public Jwt getJwt() { - return jwt; - } - - public void setJwt(Jwt jwt) { - this.jwt = jwt; - } - /************************** * Static classes *************************/ @@ -132,6 +76,7 @@ public void setJwt(Jwt jwt) { /** * Recaptcha related properties */ + @Getter @Setter public static class Recaptcha { /** @@ -143,28 +88,13 @@ public static class Recaptcha { * Google ReCaptcha Secret Key */ private String secretkey; - - public String getSitekey() { - return sitekey; - } - - public void setSitekey(String sitekey) { - this.sitekey = sitekey; - } - - public String getSecretkey() { - return secretkey; - } - - public void setSecretkey(String secretkey) { - this.secretkey = secretkey; - } } /** * CORS configuration related properties */ + @Getter @Setter public static class Cors { /** @@ -228,47 +158,6 @@ public static class Cors { * CORS maxAge long property */ private long maxAge = 3600L; - - public String[] getAllowedOrigins() { - return allowedOrigins; - } - - public void setAllowedOrigins(String[] allowedOrigins) { - this.allowedOrigins = allowedOrigins; - } - - public String[] getAllowedMethods() { - return allowedMethods; - } - - public void setAllowedMethods(String[] allowedMethods) { - this.allowedMethods = allowedMethods; - } - - public String[] getAllowedHeaders() { - return allowedHeaders; - } - - public void setAllowedHeaders(String[] allowedHeaders) { - this.allowedHeaders = allowedHeaders; - } - - public String[] getExposedHeaders() { - return exposedHeaders; - } - - public void setExposedHeaders(String[] exposedHeaders) { - this.exposedHeaders = exposedHeaders; - } - - public long getMaxAge() { - return maxAge; - } - - public void setMaxAge(long maxAge) { - this.maxAge = maxAge; - } - } @@ -277,6 +166,7 @@ public void setMaxAge(long maxAge) { * * @author Sanjay Patel */ + @Getter @Setter public static class Admin { /** @@ -288,22 +178,6 @@ public static class Admin { * Password of the initial Admin user to be created */ private String password; - - public String getUsername() { - return username; - } - - public void setUsername(String username) { - this.username = username; - } - - public String getPassword() { - return password; - } - - public void setPassword(String password) { - this.password = password; - } } /** @@ -311,6 +185,7 @@ public void setPassword(String password) { * * @author Sanjay Patel */ + @Getter @Setter public static class Jwt { /** @@ -327,29 +202,5 @@ public static class Jwt { * Expiration milliseconds for short-lived tokens and cookies */ private int shortLivedMillis = 120000; // Two minutes - - public String getSecret() { - return secret; - } - - public void setSecret(String secret) { - this.secret = secret; - } - - public long getExpirationMillis() { - return expirationMillis; - } - - public void setExpirationMillis(long expirationMillis) { - this.expirationMillis = expirationMillis; - } - - public int getShortLivedMillis() { - return shortLivedMillis; - } - - public void setShortLivedMillis(int shortLivedMillis) { - this.shortLivedMillis = shortLivedMillis; - } } } diff --git a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/domain/ChangePasswordForm.java b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/domain/ChangePasswordForm.java index 8846cd72..06d8c1df 100644 --- a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/domain/ChangePasswordForm.java +++ b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/domain/ChangePasswordForm.java @@ -4,22 +4,20 @@ import com.naturalprogrammer.spring.lemon.commons.validation.RetypePassword; import com.naturalprogrammer.spring.lemon.commons.validation.RetypePasswordForm; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + /** * Change password form. * * @author Sanjay Patel */ @RetypePassword +@Getter @Setter @NoArgsConstructor @AllArgsConstructor public class ChangePasswordForm implements RetypePasswordForm { - public ChangePasswordForm() {} - - public ChangePasswordForm(String oldPassword, String password, String retypePassword) { - this.oldPassword = oldPassword; - this.password = password; - this.retypePassword = retypePassword; - } - @Password private String oldPassword; @@ -28,29 +26,4 @@ public ChangePasswordForm(String oldPassword, String password, String retypePass @Password private String retypePassword; - - public String getPassword() { - return password; - } - - public void setPassword(String password) { - this.password = password; - } - - public String getOldPassword() { - return oldPassword; - } - - public void setOldPassword(String oldPassword) { - this.oldPassword = oldPassword; - } - - public String getRetypePassword() { - return retypePassword; - } - - public void setRetypePassword(String retypePassword) { - this.retypePassword = retypePassword; - } - } diff --git a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/mail/LemonMailData.java b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/mail/LemonMailData.java index 4105a235..eaf51c4c 100644 --- a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/mail/LemonMailData.java +++ b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/mail/LemonMailData.java @@ -1,34 +1,19 @@ package com.naturalprogrammer.spring.lemon.commons.mail; +import lombok.Getter; +import lombok.Setter; + /** * Data needed for sending a mail. * Override this if you need more data to be sent. */ +@Getter @Setter public class LemonMailData { private String to; private String subject; private String body; - - public String getTo() { - return to; - } - public void setTo(String to) { - this.to = to; - } - public String getSubject() { - return subject; - } - public void setSubject(String subject) { - this.subject = subject; - } - public String getBody() { - return body; - } - public void setBody(String body) { - this.body = body; - } - + public static LemonMailData of(String to, String subject, String body) { LemonMailData data = new LemonMailData(); diff --git a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/util/LecUtils.java b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/util/LecUtils.java index b04205d0..485cbc0d 100644 --- a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/util/LecUtils.java +++ b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/util/LecUtils.java @@ -3,7 +3,6 @@ import java.io.IOException; import java.io.Serializable; import java.nio.charset.StandardCharsets; -import java.nio.file.Files; import java.util.HashMap; import java.util.Map; import java.util.Scanner; diff --git a/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/LemonFieldError.java b/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/LemonFieldError.java index 2a77ee5c..bc47d047 100644 --- a/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/LemonFieldError.java +++ b/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/LemonFieldError.java @@ -14,7 +14,6 @@ import lombok.AllArgsConstructor; import lombok.Getter; -import lombok.NoArgsConstructor; import lombok.ToString; /** diff --git a/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/MultiErrorException.java b/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/MultiErrorException.java index d83e2fcf..78ea03ef 100644 --- a/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/MultiErrorException.java +++ b/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/MultiErrorException.java @@ -7,12 +7,15 @@ import com.naturalprogrammer.spring.lemon.exceptions.util.LexUtils; +import lombok.Getter; + /** * An exception class which can contain multiple errors. * Used for validation, in service classes. * * @author Sanjay Patel */ +@Getter public class MultiErrorException extends RuntimeException { private static final long serialVersionUID = 6020532846519363456L; @@ -71,16 +74,4 @@ public String getMessage() { // return the first message return errors.get(0).getMessage(); } - - public HttpStatus getStatus() { - return status; - } - - public void setStatus(HttpStatus status) { - this.status = status; - } - - public List getErrors() { - return errors; - } } diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/domain/VersionedEntity.java b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/domain/VersionedEntity.java index c2895b6f..ae495ec2 100644 --- a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/domain/VersionedEntity.java +++ b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/domain/VersionedEntity.java @@ -5,6 +5,9 @@ import javax.persistence.MappedSuperclass; import javax.persistence.Version; +import lombok.Getter; +import lombok.Setter; + /** * Base class for all entities needing optimistic locking. @@ -12,18 +15,11 @@ * @author Sanjay Patel */ @MappedSuperclass +@Getter @Setter public abstract class VersionedEntity, ID extends Serializable> extends LemonEntity { private static final long serialVersionUID = 4310555782328370192L; @Version private Long version; - - public Long getVersion() { - return version; - } - - public void setVersion(Long version) { - this.version = version; - } } diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/util/LemonUtils.java b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/util/LemonUtils.java index 569743dd..4c479216 100644 --- a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/util/LemonUtils.java +++ b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/util/LemonUtils.java @@ -8,14 +8,12 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import org.springframework.context.ApplicationContext; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.transaction.support.TransactionSynchronizationAdapter; import org.springframework.transaction.support.TransactionSynchronizationManager; -import com.fasterxml.jackson.databind.ObjectMapper; import com.naturalprogrammer.spring.lemon.commons.security.JwtService; import com.naturalprogrammer.spring.lemon.commons.security.LemonPrincipal; import com.naturalprogrammer.spring.lemon.commons.security.UserDto; From ed712d467e49ca05baff76876c83d7ad123ca704 Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Mon, 23 Jul 2018 20:17:49 +0530 Subject: [PATCH 024/116] Fixed #13: Rename AuthenticationSuccessHandler to LemonAuthenticationSuccessHandler --- .../spring/lemon/LemonAutoConfiguration.java | 8 ++++---- ...andler.java => LemonAuthenticationSuccessHandler.java} | 6 +++--- .../spring/lemon/security/LemonSecurityConfig.java | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) rename spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/{AuthenticationSuccessHandler.java => LemonAuthenticationSuccessHandler.java} (87%) diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/LemonAutoConfiguration.java b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/LemonAutoConfiguration.java index 7284f472..f8f2baa7 100644 --- a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/LemonAutoConfiguration.java +++ b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/LemonAutoConfiguration.java @@ -44,7 +44,7 @@ import com.naturalprogrammer.spring.lemon.exceptions.ErrorResponseComposer; import com.naturalprogrammer.spring.lemon.exceptions.LemonErrorAttributes; import com.naturalprogrammer.spring.lemon.exceptions.LemonErrorController; -import com.naturalprogrammer.spring.lemon.security.AuthenticationSuccessHandler; +import com.naturalprogrammer.spring.lemon.security.LemonAuthenticationSuccessHandler; import com.naturalprogrammer.spring.lemon.security.JwtAuthenticationProvider; import com.naturalprogrammer.spring.lemon.security.LemonCorsConfig; import com.naturalprogrammer.spring.lemon.security.LemonOAuth2UserService; @@ -159,12 +159,12 @@ public ErrorController errorController(ErrorAttributes errorAttributes, * Configures AuthenticationSuccessHandler if missing */ @Bean - @ConditionalOnMissingBean(AuthenticationSuccessHandler.class) - public AuthenticationSuccessHandler authenticationSuccessHandler( + @ConditionalOnMissingBean(LemonAuthenticationSuccessHandler.class) + public LemonAuthenticationSuccessHandler authenticationSuccessHandler( ObjectMapper objectMapper, LemonService lemonService, LemonProperties properties) { log.info("Configuring AuthenticationSuccessHandler"); - return new AuthenticationSuccessHandler(objectMapper, lemonService, properties); + return new LemonAuthenticationSuccessHandler(objectMapper, lemonService, properties); } /** diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/AuthenticationSuccessHandler.java b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonAuthenticationSuccessHandler.java similarity index 87% rename from spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/AuthenticationSuccessHandler.java rename to spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonAuthenticationSuccessHandler.java index 989450cf..e177ccf8 100644 --- a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/AuthenticationSuccessHandler.java +++ b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonAuthenticationSuccessHandler.java @@ -24,16 +24,16 @@ * * @author Sanjay Patel */ -public class AuthenticationSuccessHandler +public class LemonAuthenticationSuccessHandler extends SimpleUrlAuthenticationSuccessHandler { - private static final Log log = LogFactory.getLog(AuthenticationSuccessHandler.class); + private static final Log log = LogFactory.getLog(LemonAuthenticationSuccessHandler.class); private ObjectMapper objectMapper; private LemonService lemonService; private long defaultExpirationMillis; - public AuthenticationSuccessHandler(ObjectMapper objectMapper, LemonService lemonService, LemonProperties properties) { + public LemonAuthenticationSuccessHandler(ObjectMapper objectMapper, LemonService lemonService, LemonProperties properties) { this.objectMapper = objectMapper; this.lemonService = lemonService; diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonSecurityConfig.java b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonSecurityConfig.java index c4a9beab..f0cd5116 100644 --- a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonSecurityConfig.java +++ b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonSecurityConfig.java @@ -28,7 +28,7 @@ public class LemonSecurityConfig extends WebSecurityConfigurerAdapter { private LemonProperties properties; private UserDetailsService userDetailsService; - private AuthenticationSuccessHandler authenticationSuccessHandler; + private LemonAuthenticationSuccessHandler authenticationSuccessHandler; private AuthenticationFailureHandler authenticationFailureHandler; private LemonOidcUserService oidcUserService; private LemonOAuth2UserService oauth2UserService; @@ -39,7 +39,7 @@ public class LemonSecurityConfig extends WebSecurityConfigurerAdapter { @Autowired public void createLemonSecurityConfig(LemonProperties properties, UserDetailsService userDetailsService, - AuthenticationSuccessHandler authenticationSuccessHandler, AuthenticationFailureHandler authenticationFailureHandler, + LemonAuthenticationSuccessHandler authenticationSuccessHandler, AuthenticationFailureHandler authenticationFailureHandler, LemonOidcUserService oidcUserService, LemonOAuth2UserService oauth2UserService, OAuth2AuthenticationSuccessHandler oauth2AuthenticationSuccessHandler, From ca32ddf6e4fa1bae3d06b6f300fc9d1455c49df2 Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Mon, 23 Jul 2018 20:31:16 +0530 Subject: [PATCH 025/116] Organized imports --- .../naturalprogrammer/spring/lemon/LemonAutoConfiguration.java | 2 +- .../spring/lemonreactive/LemonReactiveController.java | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/LemonAutoConfiguration.java b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/LemonAutoConfiguration.java index f8f2baa7..731abe7d 100644 --- a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/LemonAutoConfiguration.java +++ b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/LemonAutoConfiguration.java @@ -44,8 +44,8 @@ import com.naturalprogrammer.spring.lemon.exceptions.ErrorResponseComposer; import com.naturalprogrammer.spring.lemon.exceptions.LemonErrorAttributes; import com.naturalprogrammer.spring.lemon.exceptions.LemonErrorController; -import com.naturalprogrammer.spring.lemon.security.LemonAuthenticationSuccessHandler; import com.naturalprogrammer.spring.lemon.security.JwtAuthenticationProvider; +import com.naturalprogrammer.spring.lemon.security.LemonAuthenticationSuccessHandler; import com.naturalprogrammer.spring.lemon.security.LemonCorsConfig; import com.naturalprogrammer.spring.lemon.security.LemonOAuth2UserService; import com.naturalprogrammer.spring.lemon.security.LemonOidcUserService; diff --git a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveController.java b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveController.java index 245b2070..569e3103 100644 --- a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveController.java +++ b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveController.java @@ -11,7 +11,6 @@ import org.apache.commons.logging.LogFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; -import org.springframework.http.MediaType; import org.springframework.http.server.reactive.ServerHttpResponse; import org.springframework.security.core.Authentication; import org.springframework.security.core.context.ReactiveSecurityContextHolder; From 33203ed4a516a462e9614640a9305a254b77a8b6 Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Thu, 26 Jul 2018 11:18:08 +0530 Subject: [PATCH 026/116] Updated README --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 0d03ce15..45aa3108 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ # Spring Lemon +> Take our in-depth consulting/training on Spring and minimize your development cost. [Contact us](https://www.naturalprogrammer.com/) for details. + When developing **real-world** Spring REST services for JavaScript web applications, mobile clients or any consumer, you face many challenges, such as 1. How to make the API truly _stateless_, using token authentication, session sliding etc. @@ -11,6 +13,7 @@ When developing **real-world** Spring REST services for JavaScript web applicati 1. How to do _Captcha validation_. 1. How to properly organize _application properties_. 1. How to use _PATCH_ and _JsonPatch_ to handle partial updates correctly. +1. How to do all the above reactively, using WebFlux and WebFlux security. Coding all the above effectively needs in-depth knowledge of Spring. It also takes a lot of development time and effort, and needs to be properly maintained as new versions of Spring modules come out. From 9343d9dfdfbe94047b2237ec05bae276966c0910 Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Thu, 26 Jul 2018 11:21:36 +0530 Subject: [PATCH 027/116] Updated README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 45aa3108..0761934d 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Spring Lemon -> Take our in-depth consulting/training on Spring and minimize your development cost. [Contact us](https://www.naturalprogrammer.com/) for details. +> Minimize your development cost by taking our in-depth consulting/training on Spring. [Click here](https://www.naturalprogrammer.com/) for details. When developing **real-world** Spring REST services for JavaScript web applications, mobile clients or any consumer, you face many challenges, such as From 63929189754c39bb847e72e019762d5051c15188 Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Thu, 26 Jul 2018 11:27:34 +0530 Subject: [PATCH 028/116] Updated README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 0761934d..0e6ee67d 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,7 @@ Watch [this video tutorial](https://www.naturalprogrammer.com/p/spring-lemon-res ## Documentation and Resources -> _Our [Spring Framework Recipes For Real World Application Development](https://www.naturalprogrammer.com/p/spring-framework-book-of-best-practices) — a live book discussing key real-world topics on developing Spring applications and APIs, including many Spring Lemon topics — is now available for FREE._ +> _Our [Spring Framework Recipes For Real World Application Development](https://www.naturalprogrammer.com/p/spring-framework-book-of-best-practices) — a live book discussing key real-world topics on developing Spring applications and APIs, including many Spring Lemon topics — is now available. [Click here](https://www.naturalprogrammer.com/p/spring-framework-book-of-best-practices) to get it now for FREE._ 1. Feature demo: https://youtu.be/6mNg-Feq8CY 1. _Getting started guide_ From 4a4a356884ee56d3eebdfd69994be150cb6b90c3 Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Thu, 26 Jul 2018 11:29:09 +0530 Subject: [PATCH 029/116] Updated README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 0e6ee67d..7ba9fc22 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,7 @@ Watch [this video tutorial](https://www.naturalprogrammer.com/p/spring-lemon-res ## Documentation and Resources -> _Our [Spring Framework Recipes For Real World Application Development](https://www.naturalprogrammer.com/p/spring-framework-book-of-best-practices) — a live book discussing key real-world topics on developing Spring applications and APIs, including many Spring Lemon topics — is now available. [Click here](https://www.naturalprogrammer.com/p/spring-framework-book-of-best-practices) to get it now for FREE._ +> _Our [Spring Framework Recipes For Real World Application Development](https://www.naturalprogrammer.com/p/spring-framework-book-of-best-practices) — a live book discussing key real-world topics on developing Spring applications and APIs, including many Spring Lemon topics — is now available for FREE. [Click here](https://www.naturalprogrammer.com/p/spring-framework-book-of-best-practices) to get it._ 1. Feature demo: https://youtu.be/6mNg-Feq8CY 1. _Getting started guide_ From f5c7563d31a4bae0ea91600e42ed8fbd7850937f Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Wed, 1 Aug 2018 19:57:52 +0530 Subject: [PATCH 030/116] Updated README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 7ba9fc22..de99ef05 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Spring Lemon -> Minimize your development cost by taking our in-depth consulting/training on Spring. [Click here](https://www.naturalprogrammer.com/) for details. +> Minimize your development cost with our intensive consulting/training on Spring — [click here](https://www.naturalprogrammer.com/) for details. When developing **real-world** Spring REST services for JavaScript web applications, mobile clients or any consumer, you face many challenges, such as From 39baefe021061046fbf00ba28feeb2b550b2a50a Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Thu, 2 Aug 2018 20:44:20 +0530 Subject: [PATCH 031/116] Starting 1.0.0.M6 --- lemon-demo-jpa/pom.xml | 2 +- lemon-demo-reactive/pom.xml | 2 +- pom.xml | 2 +- spring-lemon-commons/pom.xml | 2 +- spring-lemon-exceptions/pom.xml | 2 +- spring-lemon-jpa/pom.xml | 2 +- spring-lemon-reactive/pom.xml | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/lemon-demo-jpa/pom.xml b/lemon-demo-jpa/pom.xml index 58ba6953..d29f7dbc 100644 --- a/lemon-demo-jpa/pom.xml +++ b/lemon-demo-jpa/pom.xml @@ -14,7 +14,7 @@ com.naturalprogrammer spring-lemon - 1.0.0.M5 + 1.0.0.M6 diff --git a/lemon-demo-reactive/pom.xml b/lemon-demo-reactive/pom.xml index adc3c87b..7b7648dd 100644 --- a/lemon-demo-reactive/pom.xml +++ b/lemon-demo-reactive/pom.xml @@ -13,7 +13,7 @@ com.naturalprogrammer spring-lemon - 1.0.0.M5 + 1.0.0.M6 diff --git a/pom.xml b/pom.xml index 082bffd0..6d4344d3 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.naturalprogrammer spring-lemon - 1.0.0.M5 + 1.0.0.M6 pom spring-lemon diff --git a/spring-lemon-commons/pom.xml b/spring-lemon-commons/pom.xml index 3f2a395e..55c6c797 100644 --- a/spring-lemon-commons/pom.xml +++ b/spring-lemon-commons/pom.xml @@ -14,7 +14,7 @@ com.naturalprogrammer spring-lemon - 1.0.0.M5 + 1.0.0.M6 diff --git a/spring-lemon-exceptions/pom.xml b/spring-lemon-exceptions/pom.xml index 7bb72c17..205cdfd0 100644 --- a/spring-lemon-exceptions/pom.xml +++ b/spring-lemon-exceptions/pom.xml @@ -13,7 +13,7 @@ com.naturalprogrammer spring-lemon - 1.0.0.M5 + 1.0.0.M6 diff --git a/spring-lemon-jpa/pom.xml b/spring-lemon-jpa/pom.xml index 6ce4d0ef..009ae5ef 100644 --- a/spring-lemon-jpa/pom.xml +++ b/spring-lemon-jpa/pom.xml @@ -13,7 +13,7 @@ com.naturalprogrammer spring-lemon - 1.0.0.M5 + 1.0.0.M6 diff --git a/spring-lemon-reactive/pom.xml b/spring-lemon-reactive/pom.xml index ab46496d..94cdeb66 100644 --- a/spring-lemon-reactive/pom.xml +++ b/spring-lemon-reactive/pom.xml @@ -13,7 +13,7 @@ com.naturalprogrammer spring-lemon - 1.0.0.M5 + 1.0.0.M6 From 93b6be088e6be5eb14940f3e5e95f237ec883c1f Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Sat, 4 Aug 2018 19:59:14 +0530 Subject: [PATCH 032/116] Tiny enhancements --- .../lemondemo/LemonDemoReactiveApplication.java | 12 +----------- .../spring/lemon/commons/security/JwtService.java | 1 + .../lemonreactive/LemonReactiveController.java | 7 +++---- .../spring/lemonreactive/LemonReactiveService.java | 12 ++++++------ .../security/LemonReactiveSecurityConfig.java | 4 ++-- 5 files changed, 13 insertions(+), 23 deletions(-) diff --git a/lemon-demo-reactive/src/main/java/com/naturalprogrammer/spring/lemondemo/LemonDemoReactiveApplication.java b/lemon-demo-reactive/src/main/java/com/naturalprogrammer/spring/lemondemo/LemonDemoReactiveApplication.java index 25d67a53..080d31d2 100644 --- a/lemon-demo-reactive/src/main/java/com/naturalprogrammer/spring/lemondemo/LemonDemoReactiveApplication.java +++ b/lemon-demo-reactive/src/main/java/com/naturalprogrammer/spring/lemondemo/LemonDemoReactiveApplication.java @@ -13,15 +13,5 @@ public class LemonDemoReactiveApplication { public static void main(String[] args) { SpringApplication.run(LemonDemoReactiveApplication.class, args); - } - - @Bean - public SimpleModule objectIdModule() { - - SimpleModule module = new SimpleModule(); - module.setMixInAnnotation(User.class, AbstractMongoUser.class); - //module.addSerializer(ObjectId.class, new ToStringSerializer()); - - return module; - } + } } diff --git a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/JwtService.java b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/JwtService.java index 56705111..db5bd846 100644 --- a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/JwtService.java +++ b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/JwtService.java @@ -45,6 +45,7 @@ public class JwtService { public static final String VERIFY_AUDIENCE = "verify"; public static final String FORGOT_PASSWORD_AUDIENCE = "forgot-password"; public static final String CHANGE_EMAIL_AUDIENCE = "change-email"; + public static final String SELF_SUFFICIENT = "sufficient"; private DirectEncrypter encrypter; private JWEHeader header = new JWEHeader(JWEAlgorithm.DIR, EncryptionMethod.A128CBC_HS256); diff --git a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveController.java b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveController.java index 569e3103..23635a9f 100644 --- a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveController.java +++ b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveController.java @@ -48,10 +48,9 @@ public class LemonReactiveController private static final Log log = LogFactory.getLog(LemonReactiveController.class); - private long jwtExpirationMillis; - private JwtService jwtService; - private LemonReactiveService lemonReactiveService; - + protected long jwtExpirationMillis; + protected JwtService jwtService; + protected LemonReactiveService lemonReactiveService; @Autowired public void createLemonController( diff --git a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveService.java b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveService.java index 4d45d0de..37e1e8a3 100644 --- a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveService.java +++ b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveService.java @@ -48,12 +48,12 @@ public abstract class LemonReactiveService private static final Log log = LogFactory.getLog(LemonReactiveService.class); - private LemonProperties properties; - private PasswordEncoder passwordEncoder; - private MailSender mailSender; - private AbstractMongoUserRepository userRepository; - private ReactiveUserDetailsService userDetailsService; - private JwtService jwtService; + protected LemonProperties properties; + protected PasswordEncoder passwordEncoder; + protected MailSender mailSender; + protected AbstractMongoUserRepository userRepository; + protected ReactiveUserDetailsService userDetailsService; + protected JwtService jwtService; @Autowired public void createLemonService(LemonProperties properties, diff --git a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/security/LemonReactiveSecurityConfig.java b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/security/LemonReactiveSecurityConfig.java index 97976766..62fdf913 100644 --- a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/security/LemonReactiveSecurityConfig.java +++ b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/security/LemonReactiveSecurityConfig.java @@ -130,12 +130,12 @@ protected ServerAuthenticationFailureHandler authenticationFailureHandler() { protected ServerAccessDeniedHandler accessDeniedHandler() { - return (webFilterExchange, exception) -> Mono.error(exception); + return (exchange, exception) -> Mono.error(exception); } protected ServerAuthenticationEntryPoint authenticationEntryPoint() { - return (webFilterExchange, exception) -> Mono.error(exception); + return (exchange, exception) -> Mono.error(exception); } } From c8d6741d21810122d2a34c33db2e4d566b636374 Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Sat, 4 Aug 2018 20:49:32 +0530 Subject: [PATCH 033/116] Added USER_CLAIM in JwtService --- .../spring/lemon/commons/security/JwtService.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/JwtService.java b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/JwtService.java index db5bd846..57e0c88a 100644 --- a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/JwtService.java +++ b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/JwtService.java @@ -41,11 +41,12 @@ public class JwtService { private static final Log log = LogFactory.getLog(JwtService.class); public static final String LEMON_IAT = "lemon-iat"; - public static final String AUTH_AUDIENCE = "auth"; + public static final String USER_CLAIM = "user"; + + public static final String AUTH_AUDIENCE = "auth"; public static final String VERIFY_AUDIENCE = "verify"; public static final String FORGOT_PASSWORD_AUDIENCE = "forgot-password"; public static final String CHANGE_EMAIL_AUDIENCE = "change-email"; - public static final String SELF_SUFFICIENT = "sufficient"; private DirectEncrypter encrypter; private JWEHeader header = new JWEHeader(JWEAlgorithm.DIR, EncryptionMethod.A128CBC_HS256); From 0d68266de2e56720b21e51a61f7b7aede77e83d5 Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Sun, 5 Aug 2018 09:29:04 +0530 Subject: [PATCH 034/116] Better exception cause --- .../exceptions/handlers/AbstractExceptionHandler.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/handlers/AbstractExceptionHandler.java b/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/handlers/AbstractExceptionHandler.java index b70cbe57..1c0fd325 100644 --- a/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/handlers/AbstractExceptionHandler.java +++ b/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/handlers/AbstractExceptionHandler.java @@ -51,7 +51,16 @@ public ErrorResponse getErrorResponse(T ex) { } errorResponse.setErrors(getErrors(ex)); + errorResponse.setException(getRootException(ex)); return errorResponse; } + + private String getRootException(Throwable ex) { + + while(ex.getCause() != null) + ex = ex.getCause(); + + return ex.getClass().getSimpleName(); + } } From f0beec26518bd44f46ff29b687645609514bfacd Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Sun, 5 Aug 2018 10:26:43 +0530 Subject: [PATCH 035/116] Better exception name --- .../handlers/AbstractExceptionHandler.java | 10 ---------- .../spring/lemon/exceptions/util/LexUtils.java | 13 +++++++++++++ .../DefaultExceptionHandlerControllerAdvice.java | 4 +++- .../lemon/exceptions/LemonErrorAttributes.java | 10 ++++++---- .../exceptions/LemonReactiveErrorAttributes.java | 6 +++++- 5 files changed, 27 insertions(+), 16 deletions(-) diff --git a/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/handlers/AbstractExceptionHandler.java b/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/handlers/AbstractExceptionHandler.java index 1c0fd325..ca79ba79 100644 --- a/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/handlers/AbstractExceptionHandler.java +++ b/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/handlers/AbstractExceptionHandler.java @@ -51,16 +51,6 @@ public ErrorResponse getErrorResponse(T ex) { } errorResponse.setErrors(getErrors(ex)); - errorResponse.setException(getRootException(ex)); - return errorResponse; } - - private String getRootException(Throwable ex) { - - while(ex.getCause() != null) - ex = ex.getCause(); - - return ex.getClass().getSimpleName(); - } } diff --git a/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/util/LexUtils.java b/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/util/LexUtils.java index 389dcf6c..400fa6c8 100644 --- a/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/util/LexUtils.java +++ b/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/util/LexUtils.java @@ -136,4 +136,17 @@ public static Supplier notFoundSupplier() { return () -> NOT_FOUND_EXCEPTION; } + + + public static String getRootExceptionName(Throwable ex) { + + if (ex == null) + return "UnknownException"; + + while(ex.getCause() != null) + ex = ex.getCause(); + + return ex.getClass().getSimpleName(); + } + } diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/DefaultExceptionHandlerControllerAdvice.java b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/DefaultExceptionHandlerControllerAdvice.java index 96f64f29..e92c427a 100644 --- a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/DefaultExceptionHandlerControllerAdvice.java +++ b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/DefaultExceptionHandlerControllerAdvice.java @@ -8,6 +8,8 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestControllerAdvice; +import com.naturalprogrammer.spring.lemon.exceptions.util.LexUtils; + /** * Handles exceptions thrown from in controllers or inner routines */ @@ -44,7 +46,7 @@ public ResponseEntity handleException(T ex) throws T { log.warn("Handling exception", ex); // We didn't do this inside compose because LemonErrorAttributes would do it differently - errorResponse.setException(ex.getClass().getSimpleName()); + errorResponse.setException(LexUtils.getRootExceptionName(ex)); return new ResponseEntity(errorResponse, HttpStatus.valueOf(errorResponse.getStatus())); } diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/LemonErrorAttributes.java b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/LemonErrorAttributes.java index 8e19bf59..72936698 100644 --- a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/LemonErrorAttributes.java +++ b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/LemonErrorAttributes.java @@ -7,6 +7,8 @@ import org.springframework.boot.web.servlet.error.DefaultErrorAttributes; import org.springframework.web.context.request.WebRequest; +import com.naturalprogrammer.spring.lemon.exceptions.util.LexUtils; + /** * Used for handling exceptions that can't be handled by * DefaultExceptionHandlerControllerAdvice, @@ -50,15 +52,15 @@ protected void addLemonErrorDetails( Throwable ex = getError(request); - if (ex == null) // sometimes getError may return null, - return; // in which case, we can't add any more details - - errorAttributes.put("exception", ex.getClass().getSimpleName()); + errorAttributes.put("exception", LexUtils.getRootExceptionName(ex)); errorResponseComposer.compose((T)ex).ifPresent(errorResponse -> { // check for null - errorResponse may have left something for the DefaultErrorAttributes + if (errorResponse.getException() != null) // In case of deserialized exception from Feign + errorAttributes.put("exception", errorResponse.getException()); + if (errorResponse.getMessage() != null) errorAttributes.put("message", errorResponse.getMessage()); diff --git a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/exceptions/LemonReactiveErrorAttributes.java b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/exceptions/LemonReactiveErrorAttributes.java index 57793866..c8619619 100644 --- a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/exceptions/LemonReactiveErrorAttributes.java +++ b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/exceptions/LemonReactiveErrorAttributes.java @@ -8,6 +8,7 @@ import org.springframework.web.reactive.function.server.ServerRequest; import com.naturalprogrammer.spring.lemon.exceptions.ErrorResponseComposer; +import com.naturalprogrammer.spring.lemon.exceptions.util.LexUtils; public class LemonReactiveErrorAttributes extends DefaultErrorAttributes { @@ -42,12 +43,15 @@ protected void addLemonErrorDetails( Throwable ex = getError(request); - errorAttributes.put("exception", ex.getClass().getSimpleName()); + errorAttributes.put("exception", LexUtils.getRootExceptionName(ex)); errorResponseComposer.compose((T)ex).ifPresent(errorResponse -> { // check for nulls - errorResponse may have left something for the DefaultErrorAttributes + if (errorResponse.getException() != null) // In case of deserialized exception from Feign + errorAttributes.put("exception", errorResponse.getException()); + if (errorResponse.getMessage() != null) errorAttributes.put("message", errorResponse.getMessage()); From 0b69f99e569dfd2c1f2329cbff9f08f03323f16d Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Sun, 5 Aug 2018 13:07:20 +0530 Subject: [PATCH 036/116] Moved serialize and deserialize to LecUtils --- .../spring/lemon/commons/util/LecUtils.java | 23 +++++++++++++++++++ ...eOAuth2AuthorizationRequestRepository.java | 12 +++------- 2 files changed, 26 insertions(+), 9 deletions(-) diff --git a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/util/LecUtils.java b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/util/LecUtils.java index 485cbc0d..6b5b9929 100644 --- a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/util/LecUtils.java +++ b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/util/LecUtils.java @@ -1,13 +1,17 @@ package com.naturalprogrammer.spring.lemon.commons.util; +import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.Serializable; import java.nio.charset.StandardCharsets; +import java.util.Base64; import java.util.HashMap; import java.util.Map; import java.util.Scanner; import java.util.UUID; +import org.apache.commons.lang3.SerializationUtils; +import org.apache.commons.lang3.Validate; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.context.ApplicationContext; @@ -16,6 +20,7 @@ import org.springframework.security.authentication.BadCredentialsException; import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContext; +import org.springframework.security.oauth2.core.endpoint.OAuth2AuthorizationRequest; import com.fasterxml.jackson.core.JsonParseException; import com.fasterxml.jackson.core.JsonProcessingException; @@ -216,4 +221,22 @@ public static T fromJson(String json, Class clazz) return objectMapper.readValue(json, clazz); } + + /** + * Serializes an object + */ + public static String serialize(Serializable obj) { + + return Base64.getUrlEncoder().encodeToString( + SerializationUtils.serialize(obj)); + } + + /** + * Deserializes an object + */ + public static T deserialize(String serializedObj) { + + return SerializationUtils.deserialize( + Base64.getUrlDecoder().decode(serializedObj)); + } } diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/HttpCookieOAuth2AuthorizationRequestRepository.java b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/HttpCookieOAuth2AuthorizationRequestRepository.java index 0e2f3f91..ea0185c8 100644 --- a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/HttpCookieOAuth2AuthorizationRequestRepository.java +++ b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/HttpCookieOAuth2AuthorizationRequestRepository.java @@ -13,6 +13,7 @@ import org.springframework.util.Assert; import com.naturalprogrammer.spring.lemon.commons.LemonProperties; +import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; import com.naturalprogrammer.spring.lemon.util.LemonUtils; /** @@ -59,7 +60,7 @@ public void saveAuthorizationRequest(OAuth2AuthorizationRequest authorizationReq return; } - Cookie cookie = new Cookie(AUTHORIZATION_REQUEST_COOKIE_NAME, serialize(authorizationRequest)); + Cookie cookie = new Cookie(AUTHORIZATION_REQUEST_COOKIE_NAME, LecUtils.serialize(authorizationRequest)); cookie.setPath("/"); cookie.setHttpOnly(true); cookie.setMaxAge(cookieExpirySecs); @@ -101,15 +102,8 @@ public static void deleteCookies(HttpServletRequest request, HttpServletResponse } } - private String serialize(OAuth2AuthorizationRequest authorizationRequest) { - - return Base64.getUrlEncoder().encodeToString( - SerializationUtils.serialize(authorizationRequest)); - } - private OAuth2AuthorizationRequest deserialize(Cookie cookie) { - return SerializationUtils.deserialize( - Base64.getUrlDecoder().decode(cookie.getValue())); + return LecUtils.deserialize(cookie.getValue()); } } From 50d9ae1ead784d2cabc30a92bac9fe037e7f7615 Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Sun, 5 Aug 2018 13:58:50 +0530 Subject: [PATCH 037/116] Token filter enhancements --- .../lemon/commons/security/UserDto.java | 11 +++++++ .../spring/lemon/commons/util/LecUtils.java | 3 -- .../spring/lemon/domain/AbstractUser.java | 12 +------- ...eOAuth2AuthorizationRequestRepository.java | 3 -- .../domain/AbstractMongoUser.java | 12 +------- .../security/LemonReactiveSecurityConfig.java | 30 ++++++++++++++----- 6 files changed, 36 insertions(+), 35 deletions(-) diff --git a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/UserDto.java b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/UserDto.java index 2fcb1974..7fa54b8d 100644 --- a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/UserDto.java +++ b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/UserDto.java @@ -4,6 +4,8 @@ import java.util.HashSet; import java.util.Set; +import com.naturalprogrammer.spring.lemon.commons.util.UserUtils; + import lombok.Getter; import lombok.Setter; @@ -25,4 +27,13 @@ public class UserDto { private boolean admin = false; private boolean goodUser = false; private boolean goodAdmin = false; + + public void initialize() { + + unverified = roles.contains(UserUtils.Role.UNVERIFIED); + blocked = roles.contains(UserUtils.Role.BLOCKED); + admin = roles.contains(UserUtils.Role.ADMIN); + goodUser = !(unverified || blocked); + goodAdmin = goodUser && admin; + } } diff --git a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/util/LecUtils.java b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/util/LecUtils.java index 6b5b9929..975c3991 100644 --- a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/util/LecUtils.java +++ b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/util/LecUtils.java @@ -1,6 +1,5 @@ package com.naturalprogrammer.spring.lemon.commons.util; -import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.Serializable; import java.nio.charset.StandardCharsets; @@ -11,7 +10,6 @@ import java.util.UUID; import org.apache.commons.lang3.SerializationUtils; -import org.apache.commons.lang3.Validate; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.context.ApplicationContext; @@ -20,7 +18,6 @@ import org.springframework.security.authentication.BadCredentialsException; import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContext; -import org.springframework.security.oauth2.core.endpoint.OAuth2AuthorizationRequest; import com.fasterxml.jackson.core.JsonParseException; import com.fasterxml.jackson.core.JsonProcessingException; diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/domain/AbstractUser.java b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/domain/AbstractUser.java index 0074bfa7..152f624b 100644 --- a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/domain/AbstractUser.java +++ b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/domain/AbstractUser.java @@ -108,18 +108,8 @@ public UserDto toUserDto() { userDto.setRoles(roles); userDto.setTag(toTag()); - boolean unverified = hasRole(UserUtils.Role.UNVERIFIED); - boolean blocked = hasRole(UserUtils.Role.BLOCKED); - boolean admin = hasRole(UserUtils.Role.ADMIN); - boolean goodUser = !(unverified || blocked); - boolean goodAdmin = goodUser && admin; + userDto.initialize(); - userDto.setAdmin(admin); - userDto.setBlocked(blocked); - userDto.setGoodAdmin(goodAdmin); - userDto.setGoodUser(goodUser); - userDto.setUnverified(unverified); - return userDto; } diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/HttpCookieOAuth2AuthorizationRequestRepository.java b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/HttpCookieOAuth2AuthorizationRequestRepository.java index ea0185c8..70b1946d 100644 --- a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/HttpCookieOAuth2AuthorizationRequestRepository.java +++ b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/HttpCookieOAuth2AuthorizationRequestRepository.java @@ -1,12 +1,9 @@ package com.naturalprogrammer.spring.lemon.security; -import java.util.Base64; - import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import org.apache.commons.lang3.SerializationUtils; import org.apache.commons.lang3.StringUtils; import org.springframework.security.oauth2.client.web.AuthorizationRequestRepository; import org.springframework.security.oauth2.core.endpoint.OAuth2AuthorizationRequest; diff --git a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/domain/AbstractMongoUser.java b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/domain/AbstractMongoUser.java index 138f93ba..c004cb63 100644 --- a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/domain/AbstractMongoUser.java +++ b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/domain/AbstractMongoUser.java @@ -87,17 +87,7 @@ public UserDto toUserDto() { userDto.setRoles(roles); userDto.setTag(toTag()); - boolean unverified = hasRole(UserUtils.Role.UNVERIFIED); - boolean blocked = hasRole(UserUtils.Role.BLOCKED); - boolean admin = hasRole(UserUtils.Role.ADMIN); - boolean goodUser = !(unverified || blocked); - boolean goodAdmin = goodUser && admin; - - userDto.setAdmin(admin); - userDto.setBlocked(blocked); - userDto.setGoodAdmin(goodAdmin); - userDto.setGoodUser(goodUser); - userDto.setUnverified(unverified); + userDto.initialize(); return userDto; } diff --git a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/security/LemonReactiveSecurityConfig.java b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/security/LemonReactiveSecurityConfig.java index 62fdf913..89183e1b 100644 --- a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/security/LemonReactiveSecurityConfig.java +++ b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/security/LemonReactiveSecurityConfig.java @@ -23,6 +23,7 @@ import com.naturalprogrammer.spring.lemon.commons.security.JwtAuthenticationToken; import com.naturalprogrammer.spring.lemon.commons.security.JwtService; import com.naturalprogrammer.spring.lemon.commons.security.LemonPrincipal; +import com.naturalprogrammer.spring.lemon.commons.security.UserDto; import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; import com.naturalprogrammer.spring.lemonreactive.domain.AbstractMongoUser; import com.naturalprogrammer.spring.lemonreactive.util.LerUtils; @@ -36,8 +37,8 @@ public class LemonReactiveSecurityConfig , ID ex private static final Log log = LogFactory.getLog(LemonReactiveSecurityConfig.class); - private JwtService jwtService; - private LemonReactiveUserDetailsService userDetailsService; + protected JwtService jwtService; + protected LemonReactiveUserDetailsService userDetailsService; public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) { @@ -94,21 +95,36 @@ protected ReactiveAuthenticationManager tokenAuthenticationManager() { JWTClaimsSet claims = jwtService.parseToken(token, JwtService.AUTH_AUDIENCE); - String username = claims.getSubject(); - - return userDetailsService.findUserByUsername(username) + UserDto userDto = getUserDto(claims); + + Mono> userDtoMono; + + if (userDto == null) { + + String username = claims.getSubject(); + + userDtoMono = userDetailsService.findUserByUsername(username) .switchIfEmpty(Mono.defer(() -> Mono.error(new UsernameNotFoundException(username)))) .doOnNext(user -> { log.debug("User found ..."); LerUtils.ensureCredentialsUpToDate(claims, user); }) - .map(AbstractMongoUser::toUserDto) - .map(LemonPrincipal::new) + .map(AbstractMongoUser::toUserDto); + } else + userDtoMono = Mono.just(userDto); + + return userDtoMono.map(LemonPrincipal::new) .doOnNext(LemonPrincipal::eraseCredentials) .map(principal -> new JwtAuthenticationToken(principal, token, principal.getAuthorities())); }; } + protected UserDto getUserDto(JWTClaimsSet claims) { + + return null; + } + + protected Function> tokenAuthenticationConverter() { return serverWebExchange -> { From a35dfc156059cc5a00d3cbe64ab795b9fd72a8f4 Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Sun, 5 Aug 2018 17:57:28 +0530 Subject: [PATCH 038/116] Removed generic param from UserDto --- .../spring/lemondemo/services/MyService.java | 10 ++++- .../LemonDemoReactiveApplication.java | 5 --- .../lemondemo/controllers/MyController.java | 2 +- .../spring/lemondemo/services/MyService.java | 7 ++- .../commons/security/LemonPrincipal.java | 7 ++- .../security/PermissionEvaluatorEntity.java | 2 +- .../lemon/commons/security/UserDto.java | 4 +- .../spring/lemon/commons/util/LecUtils.java | 8 ++-- .../spring/lemon/commons/util/UserUtils.java | 4 +- .../spring/lemon/LemonAutoConfiguration.java | 4 +- .../spring/lemon/LemonController.java | 16 +++---- .../spring/lemon/LemonService.java | 26 ++++++----- .../spring/lemon/domain/AbstractUser.java | 8 ++-- .../lemon/domain/LemonAuditorAware.java | 11 ++--- .../spring/lemon/domain/LemonEntity.java | 2 +- .../security/JwtAuthenticationProvider.java | 2 +- .../LemonAuthenticationSuccessHandler.java | 2 +- .../security/LemonOAuth2UserService.java | 6 +-- .../lemon/security/LemonOidcUserService.java | 2 +- .../security/LemonUserDetailsService.java | 4 +- .../OAuth2AuthenticationSuccessHandler.java | 2 +- .../spring/lemon/util/LemonUtils.java | 4 +- .../LemonReactiveController.java | 14 +++--- .../lemonreactive/LemonReactiveService.java | 44 ++++++++++--------- .../domain/AbstractDocument.java | 2 +- .../domain/AbstractMongoUser.java | 8 ++-- .../security/LemonReactiveSecurityConfig.java | 10 ++--- .../spring/lemonreactive/util/LerUtils.java | 4 +- 28 files changed, 117 insertions(+), 103 deletions(-) diff --git a/lemon-demo-jpa/src/main/java/com/naturalprogrammer/spring/lemondemo/services/MyService.java b/lemon-demo-jpa/src/main/java/com/naturalprogrammer/spring/lemondemo/services/MyService.java index be2754b0..b521a588 100644 --- a/lemon-demo-jpa/src/main/java/com/naturalprogrammer/spring/lemondemo/services/MyService.java +++ b/lemon-demo-jpa/src/main/java/com/naturalprogrammer/spring/lemondemo/services/MyService.java @@ -21,14 +21,14 @@ public User newUser() { } @Override - protected void updateUserFields(User user, User updatedUser, UserDto currentUser) { + protected void updateUserFields(User user, User updatedUser, UserDto currentUser) { super.updateUserFields(user, updatedUser, currentUser); user.setName(updatedUser.getName()); LemonUtils.afterCommit(() -> { - if (currentUser.getId().equals(user.getId())) + if (currentUser.getId().equals(user.getId().toString())) currentUser.setTag(user.toTag()); }); } @@ -63,4 +63,10 @@ public void fillAdditionalFields(String registrationId, User user, Map { public static final String BASE_URI = "/api/core"; @Override - public Mono> signup( + public Mono signup( @RequestBody @JsonView(UserUtils.SignupInput.class) @Validated(SignUpValidation.class) Mono user, ServerHttpResponse response) { diff --git a/lemon-demo-reactive/src/main/java/com/naturalprogrammer/spring/lemondemo/services/MyService.java b/lemon-demo-reactive/src/main/java/com/naturalprogrammer/spring/lemondemo/services/MyService.java index faf2d3f8..9f06938c 100644 --- a/lemon-demo-reactive/src/main/java/com/naturalprogrammer/spring/lemondemo/services/MyService.java +++ b/lemon-demo-reactive/src/main/java/com/naturalprogrammer/spring/lemondemo/services/MyService.java @@ -26,9 +26,14 @@ protected User createAdminUser() { } @Override - protected void updateUserFields(User user, User updatedUser, UserDto currentUser) { + protected void updateUserFields(User user, User updatedUser, UserDto currentUser) { super.updateUserFields(user, updatedUser, currentUser); user.setName(updatedUser.getName()); } + + @Override + protected ObjectId toId(String id) { + return new ObjectId(id); + } } diff --git a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/LemonPrincipal.java b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/LemonPrincipal.java index cce08e38..a2933850 100644 --- a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/LemonPrincipal.java +++ b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/LemonPrincipal.java @@ -1,6 +1,5 @@ package com.naturalprogrammer.spring.lemon.commons.security; -import java.io.Serializable; import java.util.ArrayList; import java.util.Collection; import java.util.Map; @@ -25,12 +24,12 @@ * Spring Security Principal, implementing both OidcUser, UserDetails */ @Getter @Setter @RequiredArgsConstructor -public class LemonPrincipal implements OidcUser, UserDetails, CredentialsContainer { +public class LemonPrincipal implements OidcUser, UserDetails, CredentialsContainer { private static final long serialVersionUID = -7849730155307434535L; @Getter(AccessLevel.NONE) - private final UserDto userDto; + private final UserDto userDto; private Map attributes; private String name; @@ -38,7 +37,7 @@ public class LemonPrincipal implements OidcUser, UserDe private OidcUserInfo userInfo; private OidcIdToken idToken; - public UserDto currentUser() { + public UserDto currentUser() { return userDto; } diff --git a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/PermissionEvaluatorEntity.java b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/PermissionEvaluatorEntity.java index f973ce5a..8e849e4d 100644 --- a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/PermissionEvaluatorEntity.java +++ b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/PermissionEvaluatorEntity.java @@ -6,5 +6,5 @@ public interface PermissionEvaluatorEntity { * Whether the given user has the given permission for * this entity. Override this method where you need. */ - public boolean hasPermission(UserDto currentUser, String permission); + public boolean hasPermission(UserDto currentUser, String permission); } diff --git a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/UserDto.java b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/UserDto.java index 7fa54b8d..b9720ca5 100644 --- a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/UserDto.java +++ b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/UserDto.java @@ -14,9 +14,9 @@ * mainly used for holding logged-in user data */ @Getter @Setter -public class UserDto { +public class UserDto { - private ID id; + private String id; private String username; private String password; private Set roles = new HashSet(); diff --git a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/util/LecUtils.java b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/util/LecUtils.java index 975c3991..053c3e10 100644 --- a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/util/LecUtils.java +++ b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/util/LecUtils.java @@ -67,7 +67,7 @@ public LecUtils(ApplicationContext applicationContext, * @param auth * @return */ - public static UserDto currentUser(SecurityContext context) { + public static UserDto currentUser(SecurityContext context) { return currentUser(context.getAuthentication()); } @@ -79,12 +79,12 @@ public static UserDto currentUser(SecurityContext * @param auth * @return */ - public static UserDto currentUser(Authentication auth) { + public static UserDto currentUser(Authentication auth) { if (auth != null) { Object principal = auth.getPrincipal(); - if (principal instanceof LemonPrincipal) { - return ((LemonPrincipal) principal).currentUser(); + if (principal instanceof LemonPrincipal) { + return ((LemonPrincipal) principal).currentUser(); } } return null; diff --git a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/util/UserUtils.java b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/util/UserUtils.java index 0ef06f1a..e32a60a6 100644 --- a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/util/UserUtils.java +++ b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/util/UserUtils.java @@ -44,7 +44,7 @@ public interface ChangeEmailValidation { public interface SignupInput { } - public static boolean hasPermission(ID id, UserDto currentUser, String permission) { + public static boolean hasPermission(ID id, UserDto currentUser, String permission) { log.debug("Computing " + permission + " permission for User " + id + "\n Logged in user: " + currentUser); @@ -53,7 +53,7 @@ public static boolean hasPermission(ID id, UserDto currentUser, String p if (currentUser == null) return false; - boolean isSelf = currentUser.getId().equals(id); + boolean isSelf = currentUser.getId().equals(id.toString()); return isSelf || currentUser.isGoodAdmin(); // self or admin; } diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/LemonAutoConfiguration.java b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/LemonAutoConfiguration.java index 731abe7d..8bbbaf73 100644 --- a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/LemonAutoConfiguration.java +++ b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/LemonAutoConfiguration.java @@ -112,10 +112,10 @@ public MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter( @Bean @ConditionalOnMissingBean(AuditorAware.class) public , ID extends Serializable> - AuditorAware auditorAware(AbstractUserRepository userRepository) { + AuditorAware auditorAware(LemonService lemonService) { log.info("Configuring LemonAuditorAware"); - return new LemonAuditorAware(userRepository); + return new LemonAuditorAware(lemonService); } /** diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/LemonController.java b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/LemonController.java index 835270fb..4a02e45d 100644 --- a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/LemonController.java +++ b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/LemonController.java @@ -97,7 +97,7 @@ public Map getContext( */ @PostMapping("/users") @ResponseStatus(HttpStatus.CREATED) - public UserDto signup(@RequestBody @JsonView(UserUtils.SignupInput.class) U user, + public UserDto signup(@RequestBody @JsonView(UserUtils.SignupInput.class) U user, HttpServletResponse response) { log.debug("Signing up: " + user); @@ -125,7 +125,7 @@ public void resendVerificationMail(@PathVariable("id") U user) { * Verifies current-user */ @PostMapping("/users/{id}/verification") - public UserDto verifyUser( + public UserDto verifyUser( @PathVariable ID id, @RequestParam String code, HttpServletResponse response) { @@ -153,7 +153,7 @@ public void forgotPassword(@RequestParam String email) { * Resets password after it's forgotten */ @PostMapping("/reset-password") - public UserDto resetPassword( + public UserDto resetPassword( @RequestBody ResetPasswordForm form, HttpServletResponse response) { @@ -190,7 +190,7 @@ public U fetchUserById(@PathVariable("id") U user) { * Updates a user */ @PatchMapping("/users/{id}") - public UserDto updateUser( + public UserDto updateUser( @PathVariable("id") U user, @RequestBody String patch, HttpServletResponse response) @@ -201,7 +201,7 @@ public UserDto updateUser( // ensure that the user exists LexUtils.ensureFound(user); U updatedUser = LecUtils.applyPatch(user, patch); // create a patched form - UserDto userDto = lemonService.updateUser(user, updatedUser); + UserDto userDto = lemonService.updateUser(user, updatedUser); // Send a new token for logged in user in the response userWithToken(response); @@ -244,7 +244,7 @@ public void requestEmailChange(@PathVariable("id") U user, * Changes the email */ @PostMapping("/users/{userId}/email") - public UserDto changeEmail( + public UserDto changeEmail( @PathVariable ID userId, @RequestParam String code, HttpServletResponse response) { @@ -274,9 +274,9 @@ public Map fetchNewToken( /** * returns the current user and a new authorization token in the response */ - protected UserDto userWithToken(HttpServletResponse response) { + protected UserDto userWithToken(HttpServletResponse response) { - UserDto currentUser = LemonUtils.currentUser(); + UserDto currentUser = LemonUtils.currentUser(); lemonService.addAuthHeader(response, currentUser.getUsername(), jwtExpirationMillis); return currentUser; } diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/LemonService.java b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/LemonService.java index fd484b43..dc501198 100644 --- a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/LemonService.java +++ b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/LemonService.java @@ -176,7 +176,7 @@ public Map getContext(Optional expirationMillis, HttpServl sharedProperties.put("reCaptchaSiteKey", properties.getRecaptcha().getSitekey()); sharedProperties.put("shared", properties.getShared()); - UserDto currentUser = LemonUtils.currentUser(); + UserDto currentUser = LemonUtils.currentUser(); if (currentUser != null) addAuthHeader(response, currentUser.getUsername(), expirationMillis.orElse(properties.getJwt().getExpirationMillis())); @@ -449,7 +449,7 @@ public void resetPassword(@Valid ResetPasswordForm form) { @UserEditPermission @Validated(UserUtils.UpdateValidation.class) @Transactional(propagation=Propagation.REQUIRED, readOnly=false) - public UserDto updateUser(U user, @Valid U updatedUser) { + public UserDto updateUser(U user, @Valid U updatedUser) { log.debug("Updating user: " + user); @@ -462,7 +462,7 @@ public UserDto updateUser(U user, @Valid U updatedUser) { log.debug("Updated user: " + user); - UserDto userDto = user.toUserDto(); + UserDto userDto = user.toUserDto(); userDto.setPassword(null); return userDto; } @@ -478,8 +478,8 @@ public String changePassword(U user, @Valid ChangePasswordForm changePasswordFor log.debug("Changing password for user: " + user); // Get the old password of the logged in user (logged in user may be an ADMIN) - UserDto currentUser = LemonUtils.currentUser(); - U loggedIn = userRepository.findById(currentUser.getId()).get(); + UserDto currentUser = LemonUtils.currentUser(); + U loggedIn = userRepository.findById(toId(currentUser.getId())).get(); String oldPassword = loggedIn.getPassword(); // checks @@ -499,16 +499,18 @@ public String changePassword(U user, @Valid ChangePasswordForm changePasswordFor } + protected abstract ID toId(String id); + /** * Updates the fields of the users. Override this if you have more fields. */ - protected void updateUserFields(U user, U updatedUser, UserDto currentUser) { + protected void updateUserFields(U user, U updatedUser, UserDto currentUser) { log.debug("Updating user fields for user: " + user); // Another good admin must be logged in to edit roles if (currentUser.isGoodAdmin() && - !currentUser.getId().equals(user.getId())) { + !currentUser.getId().equals(user.getId().toString())) { log.debug("Updating roles for user: " + user); @@ -620,9 +622,9 @@ public void changeEmail(ID userId, @Valid @NotBlank String changeEmailCode) { log.debug("Changing email of current user ..."); // fetch the current-user - UserDto currentUser = LemonUtils.currentUser(); + UserDto currentUser = LemonUtils.currentUser(); - LexUtils.validate(userId.equals(currentUser.getId()), + LexUtils.validate(userId.equals(toId(currentUser.getId())), "com.naturalprogrammer.spring.wrong.login").go(); U user = userRepository.findById(userId).orElseThrow(LexUtils.notFoundSupplier()); @@ -707,7 +709,7 @@ public boolean getOAuth2AccountVerified(String registrationId, Map expirationMillis, Optional optionalUsername) { - UserDto currentUser = LemonUtils.currentUser(); + UserDto currentUser = LemonUtils.currentUser(); String username = optionalUsername.orElse(currentUser.getUsername()); LecUtils.ensureAuthority(currentUser.getUsername().equals(username) || @@ -752,4 +754,8 @@ public void addAuthHeader(HttpServletResponse response, String username, Long ex LecUtils.TOKEN_PREFIX + jwtService.createToken(JwtService.AUTH_AUDIENCE, username, expirationMillis)); } + + public Optional findUserById(String id) { + return userRepository.findById(toId(id)); + } } diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/domain/AbstractUser.java b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/domain/AbstractUser.java index 152f624b..d8aa8eef 100644 --- a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/domain/AbstractUser.java +++ b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/domain/AbstractUser.java @@ -80,7 +80,7 @@ public final boolean hasRole(String role) { * on this entity. */ @Override - public boolean hasPermission(UserDto currentUser, String permission) { + public boolean hasPermission(UserDto currentUser, String permission) { return UserUtils.hasPermission(getId(), currentUser, permission); } @@ -98,11 +98,11 @@ public String toString() { /** * Makes a User DTO */ - public UserDto toUserDto() { + public UserDto toUserDto() { - UserDto userDto = new UserDto<>(); + UserDto userDto = new UserDto(); - userDto.setId(getId()); + userDto.setId(getId().toString()); userDto.setUsername(email); userDto.setPassword(password); userDto.setRoles(roles); diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/domain/LemonAuditorAware.java b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/domain/LemonAuditorAware.java index 19c955d9..2b0f7d4e 100644 --- a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/domain/LemonAuditorAware.java +++ b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/domain/LemonAuditorAware.java @@ -7,6 +7,7 @@ import org.apache.commons.logging.LogFactory; import org.springframework.data.domain.AuditorAware; +import com.naturalprogrammer.spring.lemon.LemonService; import com.naturalprogrammer.spring.lemon.commons.security.UserDto; import com.naturalprogrammer.spring.lemon.util.LemonUtils; @@ -23,22 +24,22 @@ public class LemonAuditorAware private static final Log log = LogFactory.getLog(LemonAuditorAware.class); - private AbstractUserRepository userRepository; + private LemonService lemonService; - public LemonAuditorAware(AbstractUserRepository userRepository) { + public LemonAuditorAware(LemonService lemonService) { - this.userRepository = userRepository; + this.lemonService = lemonService; log.info("Created"); } @Override public Optional getCurrentAuditor() { - UserDto currentUser = LemonUtils.currentUser(); + UserDto currentUser = LemonUtils.currentUser(); if (currentUser == null) return Optional.empty(); - return userRepository.findById(currentUser.getId()); + return lemonService.findUserById(currentUser.getId()); } } diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/domain/LemonEntity.java b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/domain/LemonEntity.java index 41ea0597..8c4085b7 100644 --- a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/domain/LemonEntity.java +++ b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/domain/LemonEntity.java @@ -26,7 +26,7 @@ public class LemonEntity, ID extends Serializable> * this entity. Override this method where you need. */ @Override - public boolean hasPermission(UserDto user, String permission) { + public boolean hasPermission(UserDto user, String permission) { return false; } diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/JwtAuthenticationProvider.java b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/JwtAuthenticationProvider.java index 69e3ff7d..c0b3258d 100644 --- a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/JwtAuthenticationProvider.java +++ b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/JwtAuthenticationProvider.java @@ -50,7 +50,7 @@ public Authentication authenticate(Authentication auth) { log.debug("User found ..."); LemonUtils.ensureCredentialsUpToDate(claims, user); - LemonPrincipal principal = new LemonPrincipal(user.toUserDto()); + LemonPrincipal principal = new LemonPrincipal(user.toUserDto()); return new JwtAuthenticationToken(principal, token, principal.getAuthorities()); } diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonAuthenticationSuccessHandler.java b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonAuthenticationSuccessHandler.java index e177ccf8..7940acd4 100644 --- a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonAuthenticationSuccessHandler.java +++ b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonAuthenticationSuccessHandler.java @@ -59,7 +59,7 @@ public void onAuthenticationSuccess(HttpServletRequest request, defaultExpirationMillis : Long.valueOf(expirationMillisStr); // get the current-user - UserDto currentUser = LemonUtils.currentUser(); + UserDto currentUser = LemonUtils.currentUser(); lemonService.addAuthHeader(response, currentUser.getUsername(), expirationMillis); diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonOAuth2UserService.java b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonOAuth2UserService.java index 7a54c47e..1ca8276a 100644 --- a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonOAuth2UserService.java +++ b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonOAuth2UserService.java @@ -53,7 +53,7 @@ public OAuth2User loadUser(OAuth2UserRequest userRequest) throws OAuth2Authentic * Builds the security principal from the given userReqest. * Registers the user if not already reqistered */ - public LemonPrincipal buildPrincipal(OAuth2User oath2User, String registrationId) { + public LemonPrincipal buildPrincipal(OAuth2User oath2User, String registrationId) { Map attributes = oath2User.getAttributes(); String email = lemonService.getOAuth2Email(registrationId, attributes); @@ -85,8 +85,8 @@ public LemonPrincipal buildPrincipal(OAuth2User oath2User, String registrati return newUser; }); - UserDto userDto = user.toUserDto(); - LemonPrincipal principal = new LemonPrincipal<>(userDto); + UserDto userDto = user.toUserDto(); + LemonPrincipal principal = new LemonPrincipal(userDto); principal.setAttributes(attributes); principal.setName(oath2User.getName()); diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonOidcUserService.java b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonOidcUserService.java index 6c81ee6f..a9740a96 100644 --- a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonOidcUserService.java +++ b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonOidcUserService.java @@ -28,7 +28,7 @@ public LemonOidcUserService(LemonOAuth2UserService oauth2UserService) { public OidcUser loadUser(OidcUserRequest userRequest) throws OAuth2AuthenticationException { OidcUser oidcUser = super.loadUser(userRequest); - LemonPrincipal principal = oauth2UserService.buildPrincipal(oidcUser, + LemonPrincipal principal = oauth2UserService.buildPrincipal(oidcUser, userRequest.getClientRegistration().getRegistrationId()); principal.setClaims(oidcUser.getClaims()); diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonUserDetailsService.java b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonUserDetailsService.java index 19e7a1ee..67889844 100644 --- a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonUserDetailsService.java +++ b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonUserDetailsService.java @@ -33,7 +33,7 @@ public LemonUserDetailsService(AbstractUserRepository userRepository) { } @Override - public LemonPrincipal loadUserByUsername(String username) + public LemonPrincipal loadUserByUsername(String username) throws UsernameNotFoundException { log.debug("Loading user having username: " + username); @@ -45,7 +45,7 @@ public LemonPrincipal loadUserByUsername(String username) log.debug("Loaded user having username: " + username); - return new LemonPrincipal<>(user.toUserDto()); + return new LemonPrincipal(user.toUserDto()); } /** diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/OAuth2AuthenticationSuccessHandler.java b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/OAuth2AuthenticationSuccessHandler.java index 6bb33f52..e44e2789 100644 --- a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/OAuth2AuthenticationSuccessHandler.java +++ b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/OAuth2AuthenticationSuccessHandler.java @@ -41,7 +41,7 @@ public OAuth2AuthenticationSuccessHandler(LemonProperties properties, JwtService protected String determineTargetUrl(HttpServletRequest request, HttpServletResponse response) { - UserDto currentUser = LemonUtils.currentUser(); + UserDto currentUser = LemonUtils.currentUser(); String shortLivedAuthToken = jwtService.createToken( JwtService.AUTH_AUDIENCE, diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/util/LemonUtils.java b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/util/LemonUtils.java index 4c479216..09f81b47 100644 --- a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/util/LemonUtils.java +++ b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/util/LemonUtils.java @@ -41,7 +41,7 @@ public LemonUtils() { /** * Gets the current-user */ - public static UserDto currentUser() { + public static UserDto currentUser() { return LecUtils.currentUser(SecurityContextHolder.getContext()); } @@ -55,7 +55,7 @@ public static UserDto currentUser() { public static , ID extends Serializable> void login(U user) { - LemonPrincipal principal = new LemonPrincipal<>(user.toUserDto()); + LemonPrincipal principal = new LemonPrincipal(user.toUserDto()); Authentication authentication = // make the authentication object new UsernamePasswordAuthenticationToken(principal, null, principal.getAuthorities()); diff --git a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveController.java b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveController.java index 23635a9f..2b3fb9b1 100644 --- a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveController.java +++ b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveController.java @@ -70,7 +70,7 @@ public void createLemonController( * A simple function for pinging this server. */ @PostMapping("/login") - public Mono> login(ServerWebExchange exchange) { + public Mono login(ServerWebExchange exchange) { log.debug("Returning current user ... "); @@ -126,7 +126,7 @@ public Mono> getContext( */ @PostMapping("/users") @ResponseStatus(HttpStatus.CREATED) - protected Mono> signup(Mono user, ServerHttpResponse response) { + protected Mono signup(Mono user, ServerHttpResponse response) { log.debug("Signing up: " + user); @@ -151,7 +151,7 @@ public Mono resendVerificationMail(@PathVariable("id") ID userId) { * Verifies current-user */ @PostMapping("/users/{id}/verification") - public Mono> verifyUser( + public Mono verifyUser( @PathVariable ID id, ServerWebExchange exchange) { @@ -177,7 +177,7 @@ public Mono forgotPassword(ServerWebExchange exchange) { * Resets password after it's forgotten */ @PostMapping("/reset-password") - public Mono> resetPassword( + public Mono resetPassword( @RequestBody @Valid Mono form, ServerHttpResponse response) { @@ -212,7 +212,7 @@ public Mono fetchUserById(@PathVariable ID id) { * Updates a user */ @PatchMapping(value = "/users/{id}") - public Mono> updateUser( + public Mono updateUser( @PathVariable ID id, @RequestBody @NotBlank Mono patch, ServerHttpResponse response) { @@ -253,7 +253,7 @@ public Mono requestEmailChange(@PathVariable ID id, * Changes the email */ @PostMapping("/users/{userId}/email") - public Mono> changeEmail( + public Mono changeEmail( @PathVariable ID userId, ServerWebExchange exchange) { @@ -282,7 +282,7 @@ public Mono> fetchNewToken(ServerWebExchange exchange) { /** * returns the current user and a new authorization token in the response */ - protected Mono> userWithToken(Mono> userDto, + protected Mono userWithToken(Mono userDto, ServerHttpResponse response) { return lemonReactiveService.userWithToken(userDto, response, jwtExpirationMillis); diff --git a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveService.java b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveService.java index 37e1e8a3..3ebc14b2 100644 --- a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveService.java +++ b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveService.java @@ -158,7 +158,7 @@ public Mono> getContext(Optional expirationMillis, Ser log.debug("Getting context ..."); - Mono>> userDtoMono = LerUtils.currentUser(); + Mono> userDtoMono = LerUtils.currentUser(); return userDtoMono.map(optionalUser -> { Map context = buildContext(); @@ -190,7 +190,7 @@ protected Map buildContext() { /** * Signs up a user. */ - public Mono> signup(Mono user) { + public Mono signup(Mono user) { log.debug("Signing up user: " + user); @@ -277,7 +277,7 @@ public Mono resendVerificationMail(ID userId) { } - protected void ensureEditable(Tuple2>> tuple) { + protected void ensureEditable(Tuple2> tuple) { LecUtils.ensureAuthority( tuple.getT1().hasPermission(tuple.getT2().orElse(null), UserUtils.Permission.EDIT), @@ -299,7 +299,7 @@ protected void resendVerificationMail(U user) { } - public Mono> verifyUser(ID userId, Mono> formData) { + public Mono verifyUser(ID userId, Mono> formData) { log.debug("Verifying user ..."); @@ -388,7 +388,7 @@ public void mailForgotPasswordLink(U user, String forgotPasswordLink) { } - public Mono> resetPassword(Mono resetPasswordForm) { + public Mono resetPassword(Mono resetPasswordForm) { return resetPasswordForm.map(form -> { @@ -434,7 +434,7 @@ public U resetPassword(Tuple3 tuple) { /** * returns the current user and a new authorization token in the response */ - public Mono> userWithToken(Mono> userDto, + public Mono userWithToken(Mono userDto, ServerHttpResponse response, long expirationMillis) { return userDto.doOnNext(user -> { @@ -444,7 +444,7 @@ public Mono> userWithToken(Mono> userDto, } - protected void addAuthHeader(ServerHttpResponse response, UserDto userDto, long expirationMillis) { + protected void addAuthHeader(ServerHttpResponse response, UserDto userDto, long expirationMillis) { log.debug("Adding auth header for " + userDto.getUsername()); @@ -482,22 +482,22 @@ public Mono fetchUserById(ID userId) { } - public Mono> updateUser(ID userId, Mono patch) { + public Mono updateUser(ID userId, Mono patch) { return Mono.zip(findUserById(userId), LerUtils.currentUser(), patch) .doOnNext(this::ensureEditable) - .map((Tuple3>, String> tuple3) -> + .map((Tuple3, String> tuple3) -> this.updateUser(tuple3.getT1(), tuple3.getT2(), tuple3.getT3())) .flatMap(userRepository::save) .map(user -> { - UserDto userDto = user.toUserDto(); + UserDto userDto = user.toUserDto(); userDto.setPassword(null); return userDto; }); } - protected U updateUser(U user, Optional> currentUser, String patch) { + protected U updateUser(U user, Optional currentUser, String patch) { log.debug("Updating user: " + user); @@ -505,7 +505,7 @@ protected U updateUser(U user, Optional> currentUser, Stri LexUtils.validate("updatedUser", updatedUser, UserUtils.UpdateValidation.class); LerUtils.ensureCorrectVersion(user, updatedUser); - updateUserFields(user, updatedUser, (UserDto) currentUser.get()); + updateUserFields(user, updatedUser, currentUser.get()); log.debug("Updated user: " + user); return user; @@ -515,13 +515,13 @@ protected U updateUser(U user, Optional> currentUser, Stri /** * Updates the fields of the users. Override this if you have more fields. */ - protected void updateUserFields(U user, U updatedUser, UserDto currentUser) { + protected void updateUserFields(U user, U updatedUser, UserDto currentUser) { log.debug("Updating user fields for user: " + user); // Another good admin must be logged in to edit roles if (currentUser.isGoodAdmin() && - !currentUser.getId().equals(user.getId())) { + !currentUser.getId().equals(user.getId().toString())) { log.debug("Updating roles for user: " + user); @@ -565,7 +565,7 @@ public Mono findUserById(ID id) { /** * Hides the confidential fields before sending to client */ - protected void hideConfidentialFields(Tuple2>> tuple) { + protected void hideConfidentialFields(Tuple2> tuple) { U user = tuple.getT1(); @@ -578,13 +578,13 @@ protected void hideConfidentialFields(Tuple2>> } - public Mono> changePassword(ID userId, Mono changePasswordForm) { + public Mono changePassword(ID userId, Mono changePasswordForm) { return Mono.zip(findUserById(userId), LerUtils.currentUser()) .doOnNext(this::ensureEditable) .flatMap(tuple -> Mono.zip( Mono.just(tuple.getT1()), - findUserById(((UserDto)tuple.getT2().get()).getId()), + findUserById(toId(tuple.getT2().get().getId())), changePasswordForm) .doOnNext(this::changePassword)) .map(Tuple2::getT1) @@ -620,7 +620,7 @@ public Mono requestEmailChange(ID userId, Mono emailForm) { .doOnNext(this::ensureEditable) .flatMap(tuple -> Mono.zip( Mono.just(tuple.getT1()), - findUserById(((UserDto)tuple.getT2().get()).getId()), + findUserById(toId(tuple.getT2().get().getId())), emailForm) .doOnNext(this::requestEmailChange)) .map(Tuple2::getT1) @@ -629,6 +629,8 @@ public Mono requestEmailChange(ID userId, Mono emailForm) { .then(); } + protected abstract ID toId(String id); + protected void requestEmailChange(Tuple3 tuple) { U user = tuple.getT1(); @@ -697,13 +699,13 @@ protected void mailChangeEmailLink(U user, String changeEmailLink) { @PreAuthorize("isAuthenticated()") - public Mono> changeEmail(ID userId, Mono> formData) { + public Mono changeEmail(ID userId, Mono> formData) { log.debug("Changing email of current user ..."); return LerUtils.currentUser() .doOnNext(currentUser -> { - LexUtils.validate(userId.equals(currentUser.get().getId()), + LexUtils.validate(userId.equals(toId(currentUser.get().getId())), "com.naturalprogrammer.spring.wrong.login").go(); }) .then(Mono.zip(findUserById(userId), formData)) @@ -771,7 +773,7 @@ public Mono> fetchNewToken(ServerWebExchange exchange) { return Mono.zip(LerUtils.currentUser(), exchange.getFormData()).map(tuple -> { - UserDto currentUser = (UserDto) tuple.getT1().get(); + UserDto currentUser = (UserDto) tuple.getT1().get(); String username = tuple.getT2().getFirst("username"); if (StringUtils.isBlank(username)) diff --git a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/domain/AbstractDocument.java b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/domain/AbstractDocument.java index 4047e7fb..11bf73b5 100644 --- a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/domain/AbstractDocument.java +++ b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/domain/AbstractDocument.java @@ -44,7 +44,7 @@ public abstract class AbstractDocument implements Permi * this entity. Override this method where you need. */ @Override - public boolean hasPermission(UserDto currentUser, String permission) { + public boolean hasPermission(UserDto currentUser, String permission) { return false; } diff --git a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/domain/AbstractMongoUser.java b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/domain/AbstractMongoUser.java index c004cb63..c8ea7d03 100644 --- a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/domain/AbstractMongoUser.java +++ b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/domain/AbstractMongoUser.java @@ -59,7 +59,7 @@ public final boolean hasRole(String role) { * on this entity. */ @Override - public boolean hasPermission(UserDto currentUser, String permission) { + public boolean hasPermission(UserDto currentUser, String permission) { return UserUtils.hasPermission(getId(), currentUser, permission); } @@ -77,11 +77,11 @@ public String toString() { /** * Makes a User DTO */ - public UserDto toUserDto() { + public UserDto toUserDto() { - UserDto userDto = new UserDto<>(); + UserDto userDto = new UserDto(); - userDto.setId(getId()); + userDto.setId(getId().toString()); userDto.setUsername(email); userDto.setPassword(password); userDto.setRoles(roles); diff --git a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/security/LemonReactiveSecurityConfig.java b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/security/LemonReactiveSecurityConfig.java index 89183e1b..f3e30493 100644 --- a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/security/LemonReactiveSecurityConfig.java +++ b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/security/LemonReactiveSecurityConfig.java @@ -95,9 +95,9 @@ protected ReactiveAuthenticationManager tokenAuthenticationManager() { JWTClaimsSet claims = jwtService.parseToken(token, JwtService.AUTH_AUDIENCE); - UserDto userDto = getUserDto(claims); + UserDto userDto = getUserDto(claims); - Mono> userDtoMono; + Mono userDtoMono; if (userDto == null) { @@ -113,13 +113,13 @@ protected ReactiveAuthenticationManager tokenAuthenticationManager() { } else userDtoMono = Mono.just(userDto); - return userDtoMono.map(LemonPrincipal::new) - .doOnNext(LemonPrincipal::eraseCredentials) + return userDtoMono.map(LemonPrincipal::new) + .doOnNext(LemonPrincipal::eraseCredentials) .map(principal -> new JwtAuthenticationToken(principal, token, principal.getAuthorities())); }; } - protected UserDto getUserDto(JWTClaimsSet claims) { + protected UserDto getUserDto(JWTClaimsSet claims) { return null; } diff --git a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/util/LerUtils.java b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/util/LerUtils.java index b554db4e..a0a9613b 100644 --- a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/util/LerUtils.java +++ b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/util/LerUtils.java @@ -41,11 +41,11 @@ public void postConstruct() { /** * Gets the current-user */ - public static Mono>> currentUser() { + public static Mono> currentUser() { return ReactiveSecurityContextHolder.getContext() .map(LecUtils::currentUser) - .map(user -> Optional.of((UserDto) user)) + .map(user -> Optional.of(user)) .defaultIfEmpty(Optional.empty()); } From 558744582b4bc29ae5496cfaa03f2d54d24a797f Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Sun, 5 Aug 2018 19:14:52 +0530 Subject: [PATCH 039/116] Added reactive end-point for fetching full token --- .../lemon/commons/security/UserDto.java | 4 +++- .../LemonReactiveController.java | 11 +++++++++++ .../lemonreactive/LemonReactiveService.java | 19 +++++++++++++++++++ .../security/LemonReactiveSecurityConfig.java | 7 ++++++- 4 files changed, 39 insertions(+), 2 deletions(-) diff --git a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/UserDto.java b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/UserDto.java index b9720ca5..7e820982 100644 --- a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/UserDto.java +++ b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/UserDto.java @@ -14,8 +14,10 @@ * mainly used for holding logged-in user data */ @Getter @Setter -public class UserDto { +public class UserDto implements Serializable { + private static final long serialVersionUID = -9134054705405149534L; + private String id; private String username; private String password; diff --git a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveController.java b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveController.java index 2b3fb9b1..d0bb3349 100644 --- a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveController.java +++ b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveController.java @@ -277,6 +277,17 @@ public Mono> fetchNewToken(ServerWebExchange exchange) { //return LecUtils.mapOf("token", lemonService.fetchNewToken(expirationMillis, username)); } + + + /** + * Fetch a self-sufficient token with embedded UserDto - for interservice communications + */ + @GetMapping("/fetch-full-token") + public Mono> fetchFullToken() { + + log.debug("Fetching a micro token"); + return lemonReactiveService.fetchFullToken(); + } /** diff --git a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveService.java b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveService.java index 3ebc14b2..ac2490f5 100644 --- a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveService.java +++ b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveService.java @@ -790,6 +790,25 @@ public Mono> fetchNewToken(ServerWebExchange exchange) { } + @PreAuthorize("isAuthenticated()") + public Mono> fetchFullToken() { + + return LerUtils.currentUser().map(optionalUser -> { + + UserDto currentUser = optionalUser.get(); + + Map claimMap = Collections.singletonMap(JwtService.USER_CLAIM, LecUtils.serialize(currentUser)); + + Map tokenMap = Collections.singletonMap("token", LecUtils.TOKEN_PREFIX + + jwtService.createToken(JwtService.AUTH_AUDIENCE, currentUser.getUsername(), + Long.valueOf(properties.getJwt().getShortLivedMillis()), + claimMap)); + + return tokenMap; + }); + } + + public long getExpirationMillis(MultiValueMap formData) { long expirationMillis = properties.getJwt().getExpirationMillis(); diff --git a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/security/LemonReactiveSecurityConfig.java b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/security/LemonReactiveSecurityConfig.java index f3e30493..60f49694 100644 --- a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/security/LemonReactiveSecurityConfig.java +++ b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/security/LemonReactiveSecurityConfig.java @@ -121,7 +121,12 @@ protected ReactiveAuthenticationManager tokenAuthenticationManager() { protected UserDto getUserDto(JWTClaimsSet claims) { - return null; + Object userClaim = claims.getClaim(JwtService.USER_CLAIM); + + if (userClaim == null) + return null; + + return LecUtils.deserialize((String) userClaim); } From ab45621d17408773a1a8f27b5e82318299a8acac Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Sun, 5 Aug 2018 21:10:29 +0530 Subject: [PATCH 040/116] Created spring-lemon-commons-reactive module --- pom.xml | 1 + spring-lemon-commons-reactive/pom.xml | 51 ++++++ ...LemonCommonsReactiveAutoConfiguration.java | 119 ++++++++++++++ .../LemonReactiveErrorAttributes.java | 2 +- .../LemonCommonsReactiveSecurityConfig.java | 149 ++++++++++++++++++ .../security/LemonReactiveCorsConfig.java | 2 +- .../lemon/commonsreactive/util/LecrUtils.java | 59 +++++++ .../main/resources/META-INF/spring.factories | 2 + spring-lemon-reactive/pom.xml | 7 +- .../LemonReactiveAutoConfiguration.java | 78 +-------- .../lemonreactive/LemonReactiveService.java | 27 ++-- .../security/LemonReactiveSecurityConfig.java | 145 +++-------------- .../spring/lemonreactive/util/LerUtils.java | 44 ------ 13 files changed, 426 insertions(+), 260 deletions(-) create mode 100644 spring-lemon-commons-reactive/pom.xml create mode 100644 spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/LemonCommonsReactiveAutoConfiguration.java rename {spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive => spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive}/exceptions/LemonReactiveErrorAttributes.java (94%) create mode 100644 spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/security/LemonCommonsReactiveSecurityConfig.java rename {spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive => spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive}/security/LemonReactiveCorsConfig.java (90%) create mode 100644 spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/util/LecrUtils.java create mode 100644 spring-lemon-commons-reactive/src/main/resources/META-INF/spring.factories diff --git a/pom.xml b/pom.xml index 6d4344d3..9cb20b1b 100644 --- a/pom.xml +++ b/pom.xml @@ -22,6 +22,7 @@ spring-lemon-exceptions spring-lemon-commons + spring-lemon-commons-reactive spring-lemon-jpa spring-lemon-reactive lemon-demo-jpa diff --git a/spring-lemon-commons-reactive/pom.xml b/spring-lemon-commons-reactive/pom.xml new file mode 100644 index 00000000..76248da1 --- /dev/null +++ b/spring-lemon-commons-reactive/pom.xml @@ -0,0 +1,51 @@ + + + 4.0.0 + + com.naturalprogrammer.spring-lemon + spring-lemon-commons-reactive + jar + + spring-lemon-commons-reactive + >Helper reactive commons library for Spring Boot REST APIs + + + com.naturalprogrammer + spring-lemon + 1.0.0.M6 + + + + + + com.naturalprogrammer.spring-lemon + spring-lemon-commons + ${project.version} + + + + org.springframework.boot + spring-boot-starter-webflux + + + + org.mongodb + bson + + + + org.springframework.boot + spring-boot-starter-test + test + + + + io.projectreactor + reactor-test + test + + + + + diff --git a/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/LemonCommonsReactiveAutoConfiguration.java b/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/LemonCommonsReactiveAutoConfiguration.java new file mode 100644 index 00000000..d909068a --- /dev/null +++ b/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/LemonCommonsReactiveAutoConfiguration.java @@ -0,0 +1,119 @@ +package com.naturalprogrammer.spring.lemon.commonsreactive; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.bson.types.ObjectId; +import org.springframework.boot.autoconfigure.AutoConfigureBefore; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.boot.autoconfigure.security.reactive.ReactiveSecurityAutoConfiguration; +import org.springframework.boot.autoconfigure.web.reactive.WebFluxAutoConfiguration; +import org.springframework.boot.autoconfigure.web.reactive.error.ErrorWebFluxAutoConfiguration; +import org.springframework.boot.web.reactive.error.ErrorAttributes; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.access.PermissionEvaluator; +import org.springframework.security.access.expression.AbstractSecurityExpressionHandler; +import org.springframework.security.config.annotation.method.configuration.EnableReactiveMethodSecurity; +import org.springframework.security.config.web.server.ServerHttpSecurity; +import org.springframework.security.web.server.SecurityWebFilterChain; + +import com.fasterxml.jackson.databind.module.SimpleModule; +import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; +import com.naturalprogrammer.spring.lemon.commons.LemonCommonsAutoConfiguration; +import com.naturalprogrammer.spring.lemon.commons.LemonProperties; +import com.naturalprogrammer.spring.lemon.commons.security.JwtService; +import com.naturalprogrammer.spring.lemon.commonsreactive.exceptions.LemonReactiveErrorAttributes; +import com.naturalprogrammer.spring.lemon.commonsreactive.security.LemonCommonsReactiveSecurityConfig; +import com.naturalprogrammer.spring.lemon.commonsreactive.security.LemonReactiveCorsConfig; +import com.naturalprogrammer.spring.lemon.commonsreactive.util.LecrUtils; +import com.naturalprogrammer.spring.lemon.exceptions.ErrorResponseComposer; +import com.naturalprogrammer.spring.lemon.exceptions.util.LexUtils; + +@Configuration +@EnableReactiveMethodSecurity +@AutoConfigureBefore({ + WebFluxAutoConfiguration.class, + ErrorWebFluxAutoConfiguration.class, + ReactiveSecurityAutoConfiguration.class, + LemonCommonsAutoConfiguration.class}) +public class LemonCommonsReactiveAutoConfiguration { + + private static final Log log = LogFactory.getLog(LemonCommonsReactiveAutoConfiguration.class); + + public LemonCommonsReactiveAutoConfiguration() { + log.info("Created"); + } + + + /** + * Configures an Error Attributes if missing + */ + @Bean + @ConditionalOnMissingBean(ErrorAttributes.class) + public + ErrorAttributes errorAttributes(ErrorResponseComposer errorResponseComposer) { + + log.info("Configuring LemonErrorAttributes"); + return new LemonReactiveErrorAttributes(errorResponseComposer); + } + + + @Bean + @ConditionalOnMissingBean(LemonCommonsReactiveSecurityConfig.class) + public LemonCommonsReactiveSecurityConfig lemonReactiveSecurityConfig(JwtService jwtService) { + + log.info("Configuring LemonCommonsReactiveSecurityConfig ..."); + return new LemonCommonsReactiveSecurityConfig(jwtService); + } + + + /** + * Configures SecurityWebFilterChain if missing + */ + @Bean + public SecurityWebFilterChain springSecurityFilterChain( + ServerHttpSecurity http, + LemonCommonsReactiveSecurityConfig securityConfig, + AbstractSecurityExpressionHandler expressionHandler, + PermissionEvaluator permissionEvaluator) { + + log.info("Configuring SecurityWebFilterChain ..."); + expressionHandler.setPermissionEvaluator(permissionEvaluator); + return securityConfig.springSecurityFilterChain(http); + } + + + /** + * Configures LemonCorsConfig if missing and lemon.cors.allowed-origins is provided + */ + @Bean + @ConditionalOnProperty(name="lemon.cors.allowed-origins") + @ConditionalOnMissingBean(LemonReactiveCorsConfig.class) + public LemonReactiveCorsConfig lemonCorsConfig(LemonProperties properties) { + + log.info("Configuring LemonCorsConfig"); + return new LemonReactiveCorsConfig(properties); + } + + + @Bean + public SimpleModule objectIdModule() { + + SimpleModule module = new SimpleModule(); + module.addSerializer(ObjectId.class, new ToStringSerializer()); + + return module; + } + + + /** + * Configures LeeUtils + */ + @Bean + public LecrUtils lecrUtils(LexUtils lexUtils) { + + log.info("Configuring LecrUtils"); + return new LecrUtils(); + } +} diff --git a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/exceptions/LemonReactiveErrorAttributes.java b/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/exceptions/LemonReactiveErrorAttributes.java similarity index 94% rename from spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/exceptions/LemonReactiveErrorAttributes.java rename to spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/exceptions/LemonReactiveErrorAttributes.java index c8619619..5e5850a1 100644 --- a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/exceptions/LemonReactiveErrorAttributes.java +++ b/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/exceptions/LemonReactiveErrorAttributes.java @@ -1,4 +1,4 @@ -package com.naturalprogrammer.spring.lemonreactive.exceptions; +package com.naturalprogrammer.spring.lemon.commonsreactive.exceptions; import java.util.Map; diff --git a/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/security/LemonCommonsReactiveSecurityConfig.java b/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/security/LemonCommonsReactiveSecurityConfig.java new file mode 100644 index 00000000..e29a9d7b --- /dev/null +++ b/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/security/LemonCommonsReactiveSecurityConfig.java @@ -0,0 +1,149 @@ +package com.naturalprogrammer.spring.lemon.commonsreactive.security; + +import java.util.function.Function; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.springframework.http.HttpHeaders; +import org.springframework.security.authentication.AuthenticationCredentialsNotFoundException; +import org.springframework.security.authentication.ReactiveAuthenticationManager; +import org.springframework.security.config.web.server.SecurityWebFiltersOrder; +import org.springframework.security.config.web.server.ServerHttpSecurity; +import org.springframework.security.core.Authentication; +import org.springframework.security.web.server.SecurityWebFilterChain; +import org.springframework.security.web.server.ServerAuthenticationEntryPoint; +import org.springframework.security.web.server.authentication.AuthenticationWebFilter; +import org.springframework.security.web.server.authentication.ServerAuthenticationFailureHandler; +import org.springframework.security.web.server.authorization.ServerAccessDeniedHandler; +import org.springframework.security.web.server.context.NoOpServerSecurityContextRepository; +import org.springframework.web.server.ServerWebExchange; + +import com.naturalprogrammer.spring.lemon.commons.security.JwtAuthenticationToken; +import com.naturalprogrammer.spring.lemon.commons.security.JwtService; +import com.naturalprogrammer.spring.lemon.commons.security.LemonPrincipal; +import com.naturalprogrammer.spring.lemon.commons.security.UserDto; +import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; +import com.naturalprogrammer.spring.lemon.exceptions.util.LexUtils; +import com.nimbusds.jwt.JWTClaimsSet; + +import lombok.AllArgsConstructor; +import reactor.core.publisher.Mono; + +@AllArgsConstructor +public class LemonCommonsReactiveSecurityConfig { + + private static final Log log = LogFactory.getLog(LemonCommonsReactiveSecurityConfig.class); + + protected JwtService jwtService; + + public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) { + + log.info("Configuring SecurityWebFilterChain ..."); + + return formLogin(http) + .authorizeExchange() + .anyExchange().permitAll() + .and() + .securityContextRepository(NoOpServerSecurityContextRepository.getInstance()) + .exceptionHandling() + .accessDeniedHandler(accessDeniedHandler()) + .authenticationEntryPoint(authenticationEntryPoint()) + .and() + .csrf().disable() + .addFilterAt(tokenAuthenticationFilter(), SecurityWebFiltersOrder.AUTHENTICATION) + .logout().disable() + .build(); + } + + + /** + * Configure form login - only in the auth service + */ + protected ServerHttpSecurity formLogin(ServerHttpSecurity http) { + + return http; + } + + + protected AuthenticationWebFilter tokenAuthenticationFilter() { + + AuthenticationWebFilter filter = new AuthenticationWebFilter(tokenAuthenticationManager()); + filter.setAuthenticationConverter(tokenAuthenticationConverter()); + filter.setAuthenticationFailureHandler(authenticationFailureHandler()); + + return filter; + } + + protected ReactiveAuthenticationManager tokenAuthenticationManager() { + + return authentication -> { + + log.debug("Authenticating with token ..."); + + String token = (String) authentication.getCredentials(); + + JWTClaimsSet claims = jwtService.parseToken(token, JwtService.AUTH_AUDIENCE); + + UserDto userDto = getUserDto(claims); + + Mono userDtoMono = userDto == null ? + fetchUserDto(claims) : Mono.just(userDto); + + return userDtoMono.map(LemonPrincipal::new) + .doOnNext(LemonPrincipal::eraseCredentials) + .map(principal -> new JwtAuthenticationToken(principal, token, principal.getAuthorities())); + }; + } + + /** + * Default behaviour is to throw error. To be overridden in auth service. + * + * @param username + * @return + */ + protected Mono fetchUserDto(JWTClaimsSet claims) { + return Mono.error(new AuthenticationCredentialsNotFoundException( + LexUtils.getMessage("com.naturalprogrammer.spring.userNotFound", "ABSENT"))); + } + + protected UserDto getUserDto(JWTClaimsSet claims) { + + Object userClaim = claims.getClaim(JwtService.USER_CLAIM); + + if (userClaim == null) + return null; + + return LecUtils.deserialize((String) userClaim); + } + + + protected Function> tokenAuthenticationConverter() { + + return serverWebExchange -> { + + String authorization = serverWebExchange.getRequest() + .getHeaders().getFirst(HttpHeaders.AUTHORIZATION); + + if(authorization == null || !authorization.startsWith(LecUtils.TOKEN_PREFIX)) + return Mono.empty(); + + return Mono.just(new JwtAuthenticationToken(authorization.substring(7))); + }; + } + + protected ServerAuthenticationFailureHandler authenticationFailureHandler() { + + return (webFilterExchange, exception) -> Mono.error(exception); + } + + protected ServerAccessDeniedHandler accessDeniedHandler() { + + return (exchange, exception) -> Mono.error(exception); + } + + protected ServerAuthenticationEntryPoint authenticationEntryPoint() { + + return (exchange, exception) -> Mono.error(exception); + } + +} diff --git a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/security/LemonReactiveCorsConfig.java b/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/security/LemonReactiveCorsConfig.java similarity index 90% rename from spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/security/LemonReactiveCorsConfig.java rename to spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/security/LemonReactiveCorsConfig.java index 9c1e441c..bc886f98 100644 --- a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/security/LemonReactiveCorsConfig.java +++ b/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/security/LemonReactiveCorsConfig.java @@ -1,4 +1,4 @@ -package com.naturalprogrammer.spring.lemonreactive.security; +package com.naturalprogrammer.spring.lemon.commonsreactive.security; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; diff --git a/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/util/LecrUtils.java b/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/util/LecrUtils.java new file mode 100644 index 00000000..5d22fca6 --- /dev/null +++ b/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/util/LecrUtils.java @@ -0,0 +1,59 @@ +package com.naturalprogrammer.spring.lemon.commonsreactive.util; + +import java.io.IOException; +import java.io.Serializable; +import java.util.Optional; + +import javax.annotation.PostConstruct; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.springframework.security.core.context.ReactiveSecurityContextHolder; + +import com.github.fge.jsonpatch.JsonPatchException; +import com.naturalprogrammer.spring.lemon.commons.security.UserDto; +import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; +import com.naturalprogrammer.spring.lemon.exceptions.util.LexUtils; + +import reactor.core.publisher.Mono; + +/** + * Useful helper methods + * + * @author Sanjay Patel + */ +public class LecrUtils { + + private static final Log log = LogFactory.getLog(LecrUtils.class); + + private static Mono NOT_FOUND_MONO; + + @PostConstruct + public void postConstruct() { + NOT_FOUND_MONO = Mono.error(LexUtils.NOT_FOUND_EXCEPTION); + } + + /** + * Gets the current-user + */ + public static Mono> currentUser() { + + return ReactiveSecurityContextHolder.getContext() + .map(LecUtils::currentUser) + .map(user -> Optional.of(user)) + .defaultIfEmpty(Optional.empty()); + } + + public static Mono notFoundMono() { + return (Mono) NOT_FOUND_MONO; + } + + public static T applyPatch(T originalObj, String patchString) { + + try { + return LecUtils.applyPatch(originalObj, patchString); + } catch (IOException | JsonPatchException e) { + throw new RuntimeException(e); + } + } +} diff --git a/spring-lemon-commons-reactive/src/main/resources/META-INF/spring.factories b/spring-lemon-commons-reactive/src/main/resources/META-INF/spring.factories new file mode 100644 index 00000000..bf5f0b82 --- /dev/null +++ b/spring-lemon-commons-reactive/src/main/resources/META-INF/spring.factories @@ -0,0 +1,2 @@ +org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ +com.naturalprogrammer.spring.lemon.commonsreactive.LemonCommonsReactiveAutoConfiguration \ No newline at end of file diff --git a/spring-lemon-reactive/pom.xml b/spring-lemon-reactive/pom.xml index 94cdeb66..581d3e6f 100644 --- a/spring-lemon-reactive/pom.xml +++ b/spring-lemon-reactive/pom.xml @@ -20,15 +20,10 @@ com.naturalprogrammer.spring-lemon - spring-lemon-commons + spring-lemon-commons-reactive ${project.version} - - org.springframework.boot - spring-boot-starter-webflux - - org.springframework.boot spring-boot-starter-data-mongodb-reactive diff --git a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveAutoConfiguration.java b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveAutoConfiguration.java index d65ef51c..3cfea678 100644 --- a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveAutoConfiguration.java +++ b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveAutoConfiguration.java @@ -4,39 +4,23 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import org.bson.types.ObjectId; import org.springframework.boot.autoconfigure.AutoConfigureBefore; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.autoconfigure.mongo.MongoReactiveAutoConfiguration; -import org.springframework.boot.autoconfigure.security.reactive.ReactiveSecurityAutoConfiguration; import org.springframework.boot.autoconfigure.security.reactive.ReactiveUserDetailsServiceAutoConfiguration; -import org.springframework.boot.autoconfigure.web.reactive.WebFluxAutoConfiguration; -import org.springframework.boot.autoconfigure.web.reactive.error.ErrorWebFluxAutoConfiguration; -import org.springframework.boot.web.reactive.error.ErrorAttributes; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.data.mongodb.config.EnableMongoAuditing; -import org.springframework.security.access.PermissionEvaluator; -import org.springframework.security.access.expression.AbstractSecurityExpressionHandler; import org.springframework.security.config.annotation.method.configuration.EnableReactiveMethodSecurity; -import org.springframework.security.config.web.server.ServerHttpSecurity; import org.springframework.security.core.userdetails.UserDetailsService; -import org.springframework.security.web.server.SecurityWebFilterChain; -import com.fasterxml.jackson.databind.module.SimpleModule; -import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; -import com.naturalprogrammer.spring.lemon.commons.LemonCommonsAutoConfiguration; -import com.naturalprogrammer.spring.lemon.commons.LemonProperties; import com.naturalprogrammer.spring.lemon.commons.security.JwtService; -import com.naturalprogrammer.spring.lemon.exceptions.ErrorResponseComposer; +import com.naturalprogrammer.spring.lemon.commonsreactive.LemonCommonsReactiveAutoConfiguration; import com.naturalprogrammer.spring.lemon.exceptions.util.LexUtils; import com.naturalprogrammer.spring.lemonreactive.domain.AbstractMongoUser; import com.naturalprogrammer.spring.lemonreactive.domain.AbstractMongoUserRepository; -import com.naturalprogrammer.spring.lemonreactive.exceptions.LemonReactiveErrorAttributes; import com.naturalprogrammer.spring.lemonreactive.exceptions.handlers.VersionExceptionHandler; -import com.naturalprogrammer.spring.lemonreactive.security.LemonReactiveCorsConfig; import com.naturalprogrammer.spring.lemonreactive.security.LemonReactiveSecurityConfig; import com.naturalprogrammer.spring.lemonreactive.security.LemonReactiveUserDetailsService; import com.naturalprogrammer.spring.lemonreactive.util.LerUtils; @@ -46,12 +30,8 @@ @EnableReactiveMethodSecurity @AutoConfigureBefore({ MongoReactiveAutoConfiguration.class, - WebFluxAutoConfiguration.class, - ErrorWebFluxAutoConfiguration.class, -// SecurityAutoConfiguration.class, - ReactiveSecurityAutoConfiguration.class, ReactiveUserDetailsServiceAutoConfiguration.class, - LemonCommonsAutoConfiguration.class}) + LemonCommonsReactiveAutoConfiguration.class}) @ComponentScan(basePackageClasses=VersionExceptionHandler.class) public class LemonReactiveAutoConfiguration { @@ -60,21 +40,6 @@ public class LemonReactiveAutoConfiguration { public LemonReactiveAutoConfiguration() { log.info("Created"); } - - - /** - * Configures an Error Attributes if missing - */ - @Bean - @ConditionalOnMissingBean(ErrorAttributes.class) - public - ErrorAttributes errorAttributes(ErrorResponseComposer errorResponseComposer) { - - log.info("Configuring LemonErrorAttributes"); - return new LemonReactiveErrorAttributes(errorResponseComposer); - } - - @Bean @@ -90,22 +55,6 @@ LemonReactiveSecurityConfig lemonReactiveSecurityConfig( } - /** - * Configures SecurityWebFilterChain if missing - */ - @Bean - public SecurityWebFilterChain springSecurityFilterChain( - ServerHttpSecurity http, - LemonReactiveSecurityConfig securityConfig, - AbstractSecurityExpressionHandler expressionHandler, - PermissionEvaluator permissionEvaluator) { - - log.info("Configuring SecurityWebFilterChain ..."); - expressionHandler.setPermissionEvaluator(permissionEvaluator); - return securityConfig.springSecurityFilterChain(http); - } - - /** * Configures UserDetailsService if missing */ @@ -119,29 +68,6 @@ LemonReactiveUserDetailsService userDetailService(AbstractMongoUserReposi } - /** - * Configures LemonCorsConfig if missing and lemon.cors.allowed-origins is provided - */ - @Bean - @ConditionalOnProperty(name="lemon.cors.allowed-origins") - @ConditionalOnMissingBean(LemonReactiveCorsConfig.class) - public LemonReactiveCorsConfig lemonCorsConfig(LemonProperties properties) { - - log.info("Configuring LemonCorsConfig"); - return new LemonReactiveCorsConfig(properties); - } - - - @Bean - public SimpleModule objectIdModule() { - - SimpleModule module = new SimpleModule(); - module.addSerializer(ObjectId.class, new ToStringSerializer()); - - return module; - } - - /** * Configures LeeUtils */ diff --git a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveService.java b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveService.java index ac2490f5..cf0a43da 100644 --- a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveService.java +++ b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveService.java @@ -31,6 +31,7 @@ import com.naturalprogrammer.spring.lemon.commons.security.UserDto; import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; import com.naturalprogrammer.spring.lemon.commons.util.UserUtils; +import com.naturalprogrammer.spring.lemon.commonsreactive.util.LecrUtils; import com.naturalprogrammer.spring.lemon.exceptions.util.LexUtils; import com.naturalprogrammer.spring.lemonreactive.domain.AbstractMongoUser; import com.naturalprogrammer.spring.lemonreactive.domain.AbstractMongoUserRepository; @@ -158,7 +159,7 @@ public Mono> getContext(Optional expirationMillis, Ser log.debug("Getting context ..."); - Mono> userDtoMono = LerUtils.currentUser(); + Mono> userDtoMono = LecrUtils.currentUser(); return userDtoMono.map(optionalUser -> { Map context = buildContext(); @@ -270,7 +271,7 @@ protected void sendVerificationMail(final U user, String verifyLink) { public Mono resendVerificationMail(ID userId) { return findUserById(userId) - .zipWith(LerUtils.currentUser()) + .zipWith(LecrUtils.currentUser()) .doOnNext(this::ensureEditable) .map(Tuple2::getT1) .doOnNext(this::resendVerificationMail).then(); @@ -467,7 +468,7 @@ public Mono fetchUserByEmail(Mono> formData) { return email; }) .flatMap(this::findUserByEmail) - .zipWith(LerUtils.currentUser()) + .zipWith(LecrUtils.currentUser()) .doOnNext(this::hideConfidentialFields) .map(Tuple2::getT1); } @@ -476,7 +477,7 @@ public Mono fetchUserByEmail(Mono> formData) { public Mono fetchUserById(ID userId) { // fetch the user return findUserById(userId) - .zipWith(LerUtils.currentUser()) + .zipWith(LecrUtils.currentUser()) .doOnNext(this::hideConfidentialFields) .map(Tuple2::getT1); } @@ -484,7 +485,7 @@ public Mono fetchUserById(ID userId) { public Mono updateUser(ID userId, Mono patch) { - return Mono.zip(findUserById(userId), LerUtils.currentUser(), patch) + return Mono.zip(findUserById(userId), LecrUtils.currentUser(), patch) .doOnNext(this::ensureEditable) .map((Tuple3, String> tuple3) -> this.updateUser(tuple3.getT1(), tuple3.getT2(), tuple3.getT3())) @@ -501,7 +502,7 @@ protected U updateUser(U user, Optional currentUser, String patch) { log.debug("Updating user: " + user); - U updatedUser = LerUtils.applyPatch(user, patch); // create a patched form + U updatedUser = LecrUtils.applyPatch(user, patch); // create a patched form LexUtils.validate("updatedUser", updatedUser, UserUtils.UpdateValidation.class); LerUtils.ensureCorrectVersion(user, updatedUser); @@ -551,14 +552,14 @@ protected void updateUserFields(U user, U updatedUser, UserDto currentUser) { public Mono findUserByEmail(String email) { return userRepository .findByEmail(email) - .switchIfEmpty(LerUtils.notFoundMono()); + .switchIfEmpty(LecrUtils.notFoundMono()); } public Mono findUserById(ID id) { return userRepository .findById(id) - .switchIfEmpty(LerUtils.notFoundMono()); + .switchIfEmpty(LecrUtils.notFoundMono()); } @@ -580,7 +581,7 @@ protected void hideConfidentialFields(Tuple2> tuple) { public Mono changePassword(ID userId, Mono changePasswordForm) { - return Mono.zip(findUserById(userId), LerUtils.currentUser()) + return Mono.zip(findUserById(userId), LecrUtils.currentUser()) .doOnNext(this::ensureEditable) .flatMap(tuple -> Mono.zip( Mono.just(tuple.getT1()), @@ -616,7 +617,7 @@ protected void changePassword(Tuple3 tuple) { public Mono requestEmailChange(ID userId, Mono emailForm) { - return Mono.zip(findUserById(userId), LerUtils.currentUser()) + return Mono.zip(findUserById(userId), LecrUtils.currentUser()) .doOnNext(this::ensureEditable) .flatMap(tuple -> Mono.zip( Mono.just(tuple.getT1()), @@ -703,7 +704,7 @@ public Mono changeEmail(ID userId, Mono> log.debug("Changing email of current user ..."); - return LerUtils.currentUser() + return LecrUtils.currentUser() .doOnNext(currentUser -> { LexUtils.validate(userId.equals(toId(currentUser.get().getId())), "com.naturalprogrammer.spring.wrong.login").go(); @@ -771,7 +772,7 @@ protected U changeEmail(Tuple2> tuple) { @PreAuthorize("isAuthenticated()") public Mono> fetchNewToken(ServerWebExchange exchange) { - return Mono.zip(LerUtils.currentUser(), exchange.getFormData()).map(tuple -> { + return Mono.zip(LecrUtils.currentUser(), exchange.getFormData()).map(tuple -> { UserDto currentUser = (UserDto) tuple.getT1().get(); @@ -793,7 +794,7 @@ public Mono> fetchNewToken(ServerWebExchange exchange) { @PreAuthorize("isAuthenticated()") public Mono> fetchFullToken() { - return LerUtils.currentUser().map(optionalUser -> { + return LecrUtils.currentUser().map(optionalUser -> { UserDto currentUser = optionalUser.get(); diff --git a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/security/LemonReactiveSecurityConfig.java b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/security/LemonReactiveSecurityConfig.java index 60f49694..c26e9dbc 100644 --- a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/security/LemonReactiveSecurityConfig.java +++ b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/security/LemonReactiveSecurityConfig.java @@ -1,74 +1,51 @@ package com.naturalprogrammer.spring.lemonreactive.security; import java.io.Serializable; -import java.util.function.Function; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import org.springframework.http.HttpHeaders; -import org.springframework.security.authentication.ReactiveAuthenticationManager; -import org.springframework.security.config.web.server.SecurityWebFiltersOrder; import org.springframework.security.config.web.server.ServerHttpSecurity; -import org.springframework.security.core.Authentication; import org.springframework.security.core.userdetails.UsernameNotFoundException; -import org.springframework.security.web.server.SecurityWebFilterChain; -import org.springframework.security.web.server.ServerAuthenticationEntryPoint; -import org.springframework.security.web.server.authentication.AuthenticationWebFilter; -import org.springframework.security.web.server.authentication.ServerAuthenticationFailureHandler; import org.springframework.security.web.server.authentication.WebFilterChainServerAuthenticationSuccessHandler; -import org.springframework.security.web.server.authorization.ServerAccessDeniedHandler; -import org.springframework.security.web.server.context.NoOpServerSecurityContextRepository; -import org.springframework.web.server.ServerWebExchange; -import com.naturalprogrammer.spring.lemon.commons.security.JwtAuthenticationToken; import com.naturalprogrammer.spring.lemon.commons.security.JwtService; -import com.naturalprogrammer.spring.lemon.commons.security.LemonPrincipal; import com.naturalprogrammer.spring.lemon.commons.security.UserDto; -import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; +import com.naturalprogrammer.spring.lemon.commonsreactive.security.LemonCommonsReactiveSecurityConfig; import com.naturalprogrammer.spring.lemonreactive.domain.AbstractMongoUser; import com.naturalprogrammer.spring.lemonreactive.util.LerUtils; import com.nimbusds.jwt.JWTClaimsSet; -import lombok.AllArgsConstructor; import reactor.core.publisher.Mono; -@AllArgsConstructor -public class LemonReactiveSecurityConfig , ID extends Serializable> { +public class LemonReactiveSecurityConfig , ID extends Serializable> extends LemonCommonsReactiveSecurityConfig { private static final Log log = LogFactory.getLog(LemonReactiveSecurityConfig.class); - protected JwtService jwtService; protected LemonReactiveUserDetailsService userDetailsService; - public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) { + public LemonReactiveSecurityConfig(JwtService jwtService, + LemonReactiveUserDetailsService userDetailsService) { - log.info("Configuring SecurityWebFilterChain ..."); + super(jwtService); + this.userDetailsService = userDetailsService; + log.info("Created"); + } + + /** + * Configure form login + */ + @Override + protected ServerHttpSecurity formLogin(ServerHttpSecurity http) { - return http - .authorizeExchange() - .anyExchange().permitAll() - .and() - .formLogin() + return http.formLogin() .loginPage(loginPage()) // Should be "/login" by default, but not providing that overwrites our AuthenticationFailureHandler, because this is called later .authenticationFailureHandler(authenticationFailureHandler()) .authenticationSuccessHandler(new WebFilterChainServerAuthenticationSuccessHandler()) - .and() - .securityContextRepository(NoOpServerSecurityContextRepository.getInstance()) - .exceptionHandling() - .accessDeniedHandler(accessDeniedHandler()) - .authenticationEntryPoint(authenticationEntryPoint()) - .and() - .csrf().disable() - .addFilterAt(tokenAuthenticationFilter(), SecurityWebFiltersOrder.AUTHENTICATION) - .logout().disable() - .build(); + .and(); } - /** * Override this to change login URL - * - * @return */ protected String loginPage() { @@ -76,87 +53,17 @@ protected String loginPage() { } - protected AuthenticationWebFilter tokenAuthenticationFilter() { - - AuthenticationWebFilter filter = new AuthenticationWebFilter(tokenAuthenticationManager()); - filter.setAuthenticationConverter(tokenAuthenticationConverter()); - filter.setAuthenticationFailureHandler(authenticationFailureHandler()); - - return filter; - } - - protected ReactiveAuthenticationManager tokenAuthenticationManager() { - - return authentication -> { - - log.debug("Authenticating with token ..."); - - String token = (String) authentication.getCredentials(); - - JWTClaimsSet claims = jwtService.parseToken(token, JwtService.AUTH_AUDIENCE); - - UserDto userDto = getUserDto(claims); - - Mono userDtoMono; - - if (userDto == null) { - - String username = claims.getSubject(); - - userDtoMono = userDetailsService.findUserByUsername(username) - .switchIfEmpty(Mono.defer(() -> Mono.error(new UsernameNotFoundException(username)))) - .doOnNext(user -> { - log.debug("User found ..."); - LerUtils.ensureCredentialsUpToDate(claims, user); - }) - .map(AbstractMongoUser::toUserDto); - } else - userDtoMono = Mono.just(userDto); - - return userDtoMono.map(LemonPrincipal::new) - .doOnNext(LemonPrincipal::eraseCredentials) - .map(principal -> new JwtAuthenticationToken(principal, token, principal.getAuthorities())); - }; - } - - protected UserDto getUserDto(JWTClaimsSet claims) { - - Object userClaim = claims.getClaim(JwtService.USER_CLAIM); - - if (userClaim == null) - return null; - - return LecUtils.deserialize((String) userClaim); - } - - - protected Function> tokenAuthenticationConverter() { - - return serverWebExchange -> { - - String authorization = serverWebExchange.getRequest() - .getHeaders().getFirst(HttpHeaders.AUTHORIZATION); - - if(authorization == null || !authorization.startsWith(LecUtils.TOKEN_PREFIX)) - return Mono.empty(); - - return Mono.just(new JwtAuthenticationToken(authorization.substring(7))); - }; - } - - protected ServerAuthenticationFailureHandler authenticationFailureHandler() { + @Override + protected Mono fetchUserDto(JWTClaimsSet claims) { - return (webFilterExchange, exception) -> Mono.error(exception); - } - - protected ServerAccessDeniedHandler accessDeniedHandler() { + String username = claims.getSubject(); - return (exchange, exception) -> Mono.error(exception); + return userDetailsService.findUserByUsername(username) + .switchIfEmpty(Mono.defer(() -> Mono.error(new UsernameNotFoundException(username)))) + .doOnNext(user -> { + log.debug("User found ..."); + LerUtils.ensureCredentialsUpToDate(claims, user); + }) + .map(AbstractMongoUser::toUserDto); } - - protected ServerAuthenticationEntryPoint authenticationEntryPoint() { - - return (exchange, exception) -> Mono.error(exception); - } - } diff --git a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/util/LerUtils.java b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/util/LerUtils.java index a0a9613b..ac69d749 100644 --- a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/util/LerUtils.java +++ b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/util/LerUtils.java @@ -1,27 +1,17 @@ package com.naturalprogrammer.spring.lemonreactive.util; -import java.io.IOException; import java.io.Serializable; -import java.util.Optional; - -import javax.annotation.PostConstruct; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import org.springframework.security.core.context.ReactiveSecurityContextHolder; -import com.github.fge.jsonpatch.JsonPatchException; import com.naturalprogrammer.spring.lemon.commons.security.JwtService; -import com.naturalprogrammer.spring.lemon.commons.security.UserDto; import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; import com.naturalprogrammer.spring.lemon.exceptions.VersionException; -import com.naturalprogrammer.spring.lemon.exceptions.util.LexUtils; import com.naturalprogrammer.spring.lemonreactive.domain.AbstractDocument; import com.naturalprogrammer.spring.lemonreactive.domain.AbstractMongoUser; import com.nimbusds.jwt.JWTClaimsSet; -import reactor.core.publisher.Mono; - /** * Useful helper methods * @@ -31,25 +21,6 @@ public class LerUtils { private static final Log log = LogFactory.getLog(LerUtils.class); - private static Mono NOT_FOUND_MONO; - - @PostConstruct - public void postConstruct() { - NOT_FOUND_MONO = Mono.error(LexUtils.NOT_FOUND_EXCEPTION); - } - - /** - * Gets the current-user - */ - public static Mono> currentUser() { - - return ReactiveSecurityContextHolder.getContext() - .map(LecUtils::currentUser) - .map(user -> Optional.of(user)) - .defaultIfEmpty(Optional.empty()); - } - - /** * Throws BadCredentialsException if * user's credentials were updated after the JWT was issued @@ -65,12 +36,6 @@ void ensureCredentialsUpToDate(JWTClaimsSet claims, U user) { LecUtils.ensureCredentials(issueTime >= user.getCredentialsUpdatedMillis(), "com.naturalprogrammer.spring.obsoleteToken"); } - - - public static Mono notFoundMono() { - return (Mono) NOT_FOUND_MONO; - } - /** * Throws a VersionException if the versions of the @@ -85,13 +50,4 @@ void ensureCorrectVersion(AbstractDocument original, AbstractDocument up if (original.getVersion() != updated.getVersion()) throw new VersionException(original.getClass().getSimpleName(), original.getId().toString()); } - - public static T applyPatch(T originalObj, String patchString) { - - try { - return LecUtils.applyPatch(originalObj, patchString); - } catch (IOException | JsonPatchException e) { - throw new RuntimeException(e); - } - } } From 83f65dc403b727b224da29bcf20802a55d5de437 Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Mon, 6 Aug 2018 12:47:32 +0530 Subject: [PATCH 041/116] Merged ValidationMessages into messages; full token now not allowed for fetching another full token --- .../resources/ValidationMessages.properties | 12 ---- .../src/main/resources/messages.properties | 35 ++++++++++- .../resources/ValidationMessages.properties | 12 ---- .../src/main/resources/messages.properties | 33 ++++++++++ .../LemonCommonsReactiveSecurityConfig.java | 4 +- .../lemon/commons/security/JwtService.java | 63 ++++++++++++------- .../spring/lemon/commons/util/LecUtils.java | 27 +++++--- .../LemonExceptionsAutoConfiguration.java | 17 +++++ .../LemonReactiveController.java | 6 +- .../lemonreactive/LemonReactiveService.java | 8 ++- 10 files changed, 156 insertions(+), 61 deletions(-) delete mode 100644 lemon-demo-jpa/src/main/resources/ValidationMessages.properties delete mode 100644 lemon-demo-reactive/src/main/resources/ValidationMessages.properties diff --git a/lemon-demo-jpa/src/main/resources/ValidationMessages.properties b/lemon-demo-jpa/src/main/resources/ValidationMessages.properties deleted file mode 100644 index 9145571f..00000000 --- a/lemon-demo-jpa/src/main/resources/ValidationMessages.properties +++ /dev/null @@ -1,12 +0,0 @@ -com.naturalprogrammer.spring.blank.email: Email needed -com.naturalprogrammer.spring.invalid.email: Not a well formed email address -com.naturalprogrammer.spring.invalid.email.size: Email must be between {min} and {max} characters -com.naturalprogrammer.spring.duplicate.email: Email Id already used -com.naturalprogrammer.spring.wrong.captcha: Looks like you are a robot! Please try again. - -com.naturalprogrammer.spring.invalid.password.size: Password must be between {min} and {max} characters - -com.naturalprogrammer.spring.different.passwords: Passwords do not match -com.naturalprogrammer.spring.blank.password: Password needed - -blank.name: Name required diff --git a/lemon-demo-jpa/src/main/resources/messages.properties b/lemon-demo-jpa/src/main/resources/messages.properties index 852f17bb..aeed1c06 100644 --- a/lemon-demo-jpa/src/main/resources/messages.properties +++ b/lemon-demo-jpa/src/main/resources/messages.properties @@ -1,3 +1,7 @@ +# +## Spring Lemon Normal Messages +# + com.naturalprogrammer.spring.validationError: Validation Error com.naturalprogrammer.spring.verifySubject: Please verify your email id @@ -33,4 +37,33 @@ com.naturalprogrammer.spring.expiredToken: Expired token com.naturalprogrammer.spring.notGoodAdminOrSameUser: Only a good Admin or same user is permitted for this operation -com.naturalprogrammer.spring.blank: Please provide {0} \ No newline at end of file +com.naturalprogrammer.spring.blank: Please provide {0} + +com.naturalprogrammer.spring.userClaimAbsent: User claim absent in the authorization token +com.naturalprogrammer.spring.fullTokenNotAllowed: Full authorization tokens aren't allowed here + +# +## Spring Lemon Bean Validation messages +# + +com.naturalprogrammer.spring.blank.email: Email needed +com.naturalprogrammer.spring.invalid.email: Not a well formed email address +com.naturalprogrammer.spring.invalid.email.size: Email must be between {min} and {max} characters +com.naturalprogrammer.spring.duplicate.email: Email Id already used +com.naturalprogrammer.spring.wrong.captcha: Looks like you are a robot! Please try again. + +com.naturalprogrammer.spring.invalid.password.size: Password must be between {min} and {max} characters + +com.naturalprogrammer.spring.different.passwords: Passwords do not match +com.naturalprogrammer.spring.blank.password: Password needed + +# +## My Normal Messages +# + + +# +## My Bean Validation Messages +# + +blank.name: Name required diff --git a/lemon-demo-reactive/src/main/resources/ValidationMessages.properties b/lemon-demo-reactive/src/main/resources/ValidationMessages.properties deleted file mode 100644 index 9145571f..00000000 --- a/lemon-demo-reactive/src/main/resources/ValidationMessages.properties +++ /dev/null @@ -1,12 +0,0 @@ -com.naturalprogrammer.spring.blank.email: Email needed -com.naturalprogrammer.spring.invalid.email: Not a well formed email address -com.naturalprogrammer.spring.invalid.email.size: Email must be between {min} and {max} characters -com.naturalprogrammer.spring.duplicate.email: Email Id already used -com.naturalprogrammer.spring.wrong.captcha: Looks like you are a robot! Please try again. - -com.naturalprogrammer.spring.invalid.password.size: Password must be between {min} and {max} characters - -com.naturalprogrammer.spring.different.passwords: Passwords do not match -com.naturalprogrammer.spring.blank.password: Password needed - -blank.name: Name required diff --git a/lemon-demo-reactive/src/main/resources/messages.properties b/lemon-demo-reactive/src/main/resources/messages.properties index b05037fd..aeed1c06 100644 --- a/lemon-demo-reactive/src/main/resources/messages.properties +++ b/lemon-demo-reactive/src/main/resources/messages.properties @@ -1,3 +1,7 @@ +# +## Spring Lemon Normal Messages +# + com.naturalprogrammer.spring.validationError: Validation Error com.naturalprogrammer.spring.verifySubject: Please verify your email id @@ -34,3 +38,32 @@ com.naturalprogrammer.spring.expiredToken: Expired token com.naturalprogrammer.spring.notGoodAdminOrSameUser: Only a good Admin or same user is permitted for this operation com.naturalprogrammer.spring.blank: Please provide {0} + +com.naturalprogrammer.spring.userClaimAbsent: User claim absent in the authorization token +com.naturalprogrammer.spring.fullTokenNotAllowed: Full authorization tokens aren't allowed here + +# +## Spring Lemon Bean Validation messages +# + +com.naturalprogrammer.spring.blank.email: Email needed +com.naturalprogrammer.spring.invalid.email: Not a well formed email address +com.naturalprogrammer.spring.invalid.email.size: Email must be between {min} and {max} characters +com.naturalprogrammer.spring.duplicate.email: Email Id already used +com.naturalprogrammer.spring.wrong.captcha: Looks like you are a robot! Please try again. + +com.naturalprogrammer.spring.invalid.password.size: Password must be between {min} and {max} characters + +com.naturalprogrammer.spring.different.passwords: Passwords do not match +com.naturalprogrammer.spring.blank.password: Password needed + +# +## My Normal Messages +# + + +# +## My Bean Validation Messages +# + +blank.name: Name required diff --git a/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/security/LemonCommonsReactiveSecurityConfig.java b/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/security/LemonCommonsReactiveSecurityConfig.java index e29a9d7b..d88a359f 100644 --- a/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/security/LemonCommonsReactiveSecurityConfig.java +++ b/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/security/LemonCommonsReactiveSecurityConfig.java @@ -103,7 +103,7 @@ protected ReactiveAuthenticationManager tokenAuthenticationManager() { */ protected Mono fetchUserDto(JWTClaimsSet claims) { return Mono.error(new AuthenticationCredentialsNotFoundException( - LexUtils.getMessage("com.naturalprogrammer.spring.userNotFound", "ABSENT"))); + LexUtils.getMessage("com.naturalprogrammer.spring.userClaimAbsent"))); } protected UserDto getUserDto(JWTClaimsSet claims) { @@ -127,7 +127,7 @@ protected Function> tokenAuthenticationC if(authorization == null || !authorization.startsWith(LecUtils.TOKEN_PREFIX)) return Mono.empty(); - return Mono.just(new JwtAuthenticationToken(authorization.substring(7))); + return Mono.just(new JwtAuthenticationToken(authorization.substring(LecUtils.TOKEN_PREFIX_LENGTH))); }; } diff --git a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/JwtService.java b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/JwtService.java index 57e0c88a..7a71f54c 100644 --- a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/JwtService.java +++ b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/JwtService.java @@ -118,28 +118,21 @@ public String createToken(String audience, String subject, Long expirationMillis */ public JWTClaimsSet parseToken(String token, String audience) { - try { - - JWTClaimsSet claims = jwtProcessor.process(token, null); - LecUtils.ensureCredentials(audience != null && - claims.getAudience().contains(audience), - "com.naturalprogrammer.spring.wrong.audience"); - - long expirationTime = claims.getExpirationTime().getTime(); - long currentTime = System.currentTimeMillis(); - - log.debug("Parsing JWT. Expiration time = " + expirationTime - + ". Current time = " + currentTime); - - LecUtils.ensureCredentials(expirationTime >= currentTime, - "com.naturalprogrammer.spring.expiredToken"); - - return claims; - - } catch (ParseException | BadJOSEException | JOSEException e) { - - throw new BadCredentialsException(e.getMessage()); - } + JWTClaimsSet claims = parseToken(token); + LecUtils.ensureCredentials(audience != null && + claims.getAudience().contains(audience), + "com.naturalprogrammer.spring.wrong.audience"); + + long expirationTime = claims.getExpirationTime().getTime(); + long currentTime = System.currentTimeMillis(); + + log.debug("Parsing JWT. Expiration time = " + expirationTime + + ". Current time = " + currentTime); + + LecUtils.ensureCredentials(expirationTime >= currentTime, + "com.naturalprogrammer.spring.expiredToken"); + + return claims; } /** @@ -154,5 +147,29 @@ public JWTClaimsSet parseToken(String token, String audience, long issuedAfter) "com.naturalprogrammer.spring.obsoleteToken"); return claims; - } + } + + /** + * Parses a token + */ + public JWTClaimsSet parseToken(String token) { + + try { + + return jwtProcessor.process(token, null); + + } catch (ParseException | BadJOSEException | JOSEException e) { + + throw new BadCredentialsException(e.getMessage()); + } + } + + /** + * Parses a claim + */ + public T parseClaim(String token, String claim) { + + JWTClaimsSet claims = parseToken(token); + return (T) claims.getClaim(claim); + } } diff --git a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/util/LecUtils.java b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/util/LecUtils.java index 053c3e10..7911ba5e 100644 --- a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/util/LecUtils.java +++ b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/util/LecUtils.java @@ -19,10 +19,8 @@ import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContext; -import com.fasterxml.jackson.core.JsonParseException; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.TreeNode; -import com.fasterxml.jackson.databind.JsonMappingException; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.github.fge.jsonpatch.JsonPatch; @@ -46,8 +44,10 @@ public class LecUtils { // JWT Token related public static final String TOKEN_PREFIX = "Bearer "; + public static final int TOKEN_PREFIX_LENGTH = 7; public static final String TOKEN_RESPONSE_HEADER_NAME = "Lemon-Authorization"; + public static ApplicationContext applicationContext; public static ObjectMapper objectMapper; @@ -204,19 +204,32 @@ public static String uid() { /** * Serializes an object to JSON string */ - public static String toJson(T obj) throws JsonProcessingException { + public static String toJson(T obj) { - return objectMapper.writeValueAsString(obj); + try { + + return objectMapper.writeValueAsString(obj); + + } catch (JsonProcessingException e) { + + throw new RuntimeException(e); + } } /** * Deserializes a JSON String */ - public static T fromJson(String json, Class clazz) - throws JsonParseException, JsonMappingException, IOException { + public static T fromJson(String json, Class clazz) { - return objectMapper.readValue(json, clazz); + try { + + return objectMapper.readValue(json, clazz); + + } catch (IOException e) { + + throw new RuntimeException(e); + } } /** diff --git a/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/LemonExceptionsAutoConfiguration.java b/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/LemonExceptionsAutoConfiguration.java index 33354438..5e8425a0 100644 --- a/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/LemonExceptionsAutoConfiguration.java +++ b/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/LemonExceptionsAutoConfiguration.java @@ -2,9 +2,13 @@ import java.util.List; +import javax.validation.Validator; + import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.springframework.boot.autoconfigure.AutoConfigureBefore; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.validation.ValidationAutoConfiguration; import org.springframework.context.MessageSource; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; @@ -15,6 +19,7 @@ import com.naturalprogrammer.spring.lemon.exceptions.util.LexUtils; @Configuration +@AutoConfigureBefore({ValidationAutoConfiguration.class}) @ComponentScan(basePackageClasses=AbstractExceptionHandler.class) public class LemonExceptionsAutoConfiguration { @@ -47,4 +52,16 @@ public LexUtils lexUtils(MessageSource messageSource, LocalValidatorFactoryBean log.info("Configuring LexUtils"); return new LexUtils(messageSource, validator); } + + /** + * Merge ValidationMessages.properties into messages.properties + */ + @Bean + @ConditionalOnMissingBean(Validator.class) + public Validator validator(MessageSource messageSource) { + + LocalValidatorFactoryBean localValidatorFactoryBean = new LocalValidatorFactoryBean(); + localValidatorFactoryBean.setValidationMessageSource(messageSource); + return localValidatorFactoryBean; + } } diff --git a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveController.java b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveController.java index d0bb3349..10cd352c 100644 --- a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveController.java +++ b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveController.java @@ -10,6 +10,7 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.server.reactive.ServerHttpResponse; import org.springframework.security.core.Authentication; @@ -20,6 +21,7 @@ import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestHeader; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.server.ServerWebExchange; @@ -283,10 +285,10 @@ public Mono> fetchNewToken(ServerWebExchange exchange) { * Fetch a self-sufficient token with embedded UserDto - for interservice communications */ @GetMapping("/fetch-full-token") - public Mono> fetchFullToken() { + public Mono> fetchFullToken(@RequestHeader(HttpHeaders.AUTHORIZATION) String authHeader) { log.debug("Fetching a micro token"); - return lemonReactiveService.fetchFullToken(); + return lemonReactiveService.fetchFullToken(authHeader); } diff --git a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveService.java b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveService.java index cf0a43da..236a5b14 100644 --- a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveService.java +++ b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveService.java @@ -792,13 +792,17 @@ public Mono> fetchNewToken(ServerWebExchange exchange) { @PreAuthorize("isAuthenticated()") - public Mono> fetchFullToken() { + public Mono> fetchFullToken(String authHeader) { + LecUtils.ensureCredentials(jwtService.parseClaim(authHeader.substring(LecUtils.TOKEN_PREFIX_LENGTH), + JwtService.USER_CLAIM) == null, "com.naturalprogrammer.spring.fullTokenNotAllowed"); + return LecrUtils.currentUser().map(optionalUser -> { UserDto currentUser = optionalUser.get(); - Map claimMap = Collections.singletonMap(JwtService.USER_CLAIM, LecUtils.serialize(currentUser)); + Map claimMap = Collections.singletonMap(JwtService.USER_CLAIM, + LecUtils.serialize(currentUser)); // Not serializing converts it to a JsonNode Map tokenMap = Collections.singletonMap("token", LecUtils.TOKEN_PREFIX + jwtService.createToken(JwtService.AUTH_AUDIENCE, currentUser.getUsername(), From 6fa84e14a746dfbf150291b9f98211f1c3337041 Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Fri, 10 Aug 2018 17:34:54 +0530 Subject: [PATCH 042/116] Updated README --- README.md | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index de99ef05..2497fe5f 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ > Minimize your development cost with our intensive consulting/training on Spring — [click here](https://www.naturalprogrammer.com/) for details. -When developing **real-world** Spring REST services for JavaScript web applications, mobile clients or any consumer, you face many challenges, such as +When developing **real-world** Spring REST APIs and microservices, you'd face many challenges like 1. How to make the API truly _stateless_, using token authentication, session sliding etc. 1. How to configure Spring Security to suit API development, e.g. returning _200_ or _401_ responses on login, configuring _CORS_, _JSON vulnerability protection_, etc. @@ -15,11 +15,11 @@ When developing **real-world** Spring REST services for JavaScript web applicati 1. How to use _PATCH_ and _JsonPatch_ to handle partial updates correctly. 1. How to do all the above reactively, using WebFlux and WebFlux security. -Coding all the above effectively needs in-depth knowledge of Spring. It also takes a lot of development time and effort, and needs to be properly maintained as new versions of Spring modules come out. +Coding all the above correctly needs in-depth knowledge of Spring. It also takes a lot of development time and effort, and needs to be properly maintained as new versions of Spring modules come out. -To relieve you of this non-trivial job, we thought to bring out **Spring Lemon**, a tiny open source library holding all these common configuration and components, and a production grade user module with all the abovementioned features. +**Spring Lemon** relieves you of all this burden. It's a tiny open source library holding all these common configuration and components, and also a production grade user module with all the abovementioned features. -Even if you don't plan to use Spring Lemon, it's a good example application to learn from, because it showcases the essential best practices for developing elegant web services using Spring. +Even if you don't plan to use Spring Lemon, it's a good example application to learn from, because it showcases the essential best practices for developing elegant web services and microservices using Spring. Most Spring Boot applications can use Spring Lemon straight away, with some simple configurations. But, if you don't find it suitable for your application, feel free to fork it, or just roll out your own library by learning its patterns and practices. Better yet, be a contributor! @@ -36,12 +36,13 @@ Watch [this video tutorial](https://www.naturalprogrammer.com/p/spring-lemon-res 1. _[Example application](https://github.com/naturalprogrammer/spring-lemon/tree/master/lemon-demo-jpa)_ — A sample application using Spring Lemon. Quite similar to the one developed in the above [getting started guide](https://github.com/naturalprogrammer/spring-lemon/wiki/Getting-Started-With-Spring-Lemon), but additionally has automated tests. 1. _[API documentation](https://documenter.getpostman.com/view/305915/RVu2mqEH)_ of the above application. 1. _[Example AngularJS front-end application](https://github.com/naturalprogrammer/spring-lemon/tree/master/lemon-demo-angularjs)_ — A sample AngularJS 1.x front-end. It'll work both for the application developed in the above [getting started guide](https://github.com/naturalprogrammer/spring-lemon/wiki/Getting-Started-With-Spring-Lemon) as well as the [Lemon Demo application](https://github.com/naturalprogrammer/spring-lemon/tree/master/lemon-demo-jpa). See the [Getting Started Guide](https://github.com/naturalprogrammer/spring-lemon/wiki/Getting-Started-With-Spring-Lemon) on how to use it. -1. _[Spring Framework Recipes For Real World Application Development](https://www.naturalprogrammer.com/p/spring-framework-book-of-best-practices)_ — a live book discussing key real-world topics on developing Spring applications and APIs. Includes key Spring Lemon topics. [Click here](https://www.naturalprogrammer.com/p/spring-framework-book-of-best-practices) to get it now for FREE! +1. _[Example reactive microservices](https://github.com/naturalprogrammer/np-microservices-sample-02) using Spring Lemon, and its [configuration repo](https://github.com/naturalprogrammer/np-microservices-sample-02-config)_ — A sample reactive microservices application depicting how easy it is to develop reactive microservices using Spring Lemon. +1. _[Spring Framework Recipes For Real World Application Development](https://www.naturalprogrammer.com/p/spring-framework-book-of-best-practices)_ — a live book discussing key real-world topics on developing Spring applications, APIs and microservoces. Includes key Spring Lemon topics. [Click here](https://www.naturalprogrammer.com/p/spring-framework-book-of-best-practices) to get it now for FREE! 1. Video tutorials coming soon: 1. Spring Framework 5 REST API Development — A Complete Blueprint For Real-World Developers 1. Spring WebFlux Reactive REST API Development — A Complete Blueprint For Real-World Developers 1. Real World Microservices Using Spring Cloud — A Rapid Course - 1. Register [here](https://www.naturalprogrammer.com/p/spring-framework-book-of-best-practices) to get notified when the above courses get released + 1. Join [here](https://www.naturalprogrammer.com/p/spring-framework-book-of-best-practices) to get notified when the above courses get released ## Help and Support 1. Community help is available at [stackoverflow.com](http://stackoverflow.com/questions/tagged/spring-lemon), under the `spring-lemon` tag. Do not miss to tag the questions with `spring-lemon`! From 0dea96923a9a52c9d5bf7211796534f0fa463542 Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Sat, 11 Aug 2018 06:06:09 +0530 Subject: [PATCH 043/116] Updated README --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 2497fe5f..2cbcfc7e 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ > Minimize your development cost with our intensive consulting/training on Spring — [click here](https://www.naturalprogrammer.com/) for details. -When developing **real-world** Spring REST APIs and microservices, you'd face many challenges like +When developing **real-world** Spring REST APIs and microservices, you face many challenges like 1. How to make the API truly _stateless_, using token authentication, session sliding etc. 1. How to configure Spring Security to suit API development, e.g. returning _200_ or _401_ responses on login, configuring _CORS_, _JSON vulnerability protection_, etc. @@ -15,7 +15,7 @@ When developing **real-world** Spring REST APIs and microservices, you'd face ma 1. How to use _PATCH_ and _JsonPatch_ to handle partial updates correctly. 1. How to do all the above reactively, using WebFlux and WebFlux security. -Coding all the above correctly needs in-depth knowledge of Spring. It also takes a lot of development time and effort, and needs to be properly maintained as new versions of Spring modules come out. +Coding all this rightly needs in-depth knowledge of Spring. It also takes a lot of development time and effort, and needs to be properly maintained as new versions of Spring modules come out. **Spring Lemon** relieves you of all this burden. It's a tiny open source library holding all these common configuration and components, and also a production grade user module with all the abovementioned features. @@ -27,7 +27,7 @@ Watch [this video tutorial](https://www.naturalprogrammer.com/p/spring-lemon-res ## Documentation and Resources -> _Our [Spring Framework Recipes For Real World Application Development](https://www.naturalprogrammer.com/p/spring-framework-book-of-best-practices) — a live book discussing key real-world topics on developing Spring applications and APIs, including many Spring Lemon topics — is now available for FREE. [Click here](https://www.naturalprogrammer.com/p/spring-framework-book-of-best-practices) to get it._ +> _Our [Spring Framework Recipes For Real World Application Development](https://www.naturalprogrammer.com/p/spring-framework-book-of-best-practices) — a live book discussing key real-world topics on developing Spring applications and APIs — is now available for FREE. [Click here](https://www.naturalprogrammer.com/p/spring-framework-book-of-best-practices) to get it._ 1. Feature demo: https://youtu.be/6mNg-Feq8CY 1. _Getting started guide_ @@ -37,7 +37,7 @@ Watch [this video tutorial](https://www.naturalprogrammer.com/p/spring-lemon-res 1. _[API documentation](https://documenter.getpostman.com/view/305915/RVu2mqEH)_ of the above application. 1. _[Example AngularJS front-end application](https://github.com/naturalprogrammer/spring-lemon/tree/master/lemon-demo-angularjs)_ — A sample AngularJS 1.x front-end. It'll work both for the application developed in the above [getting started guide](https://github.com/naturalprogrammer/spring-lemon/wiki/Getting-Started-With-Spring-Lemon) as well as the [Lemon Demo application](https://github.com/naturalprogrammer/spring-lemon/tree/master/lemon-demo-jpa). See the [Getting Started Guide](https://github.com/naturalprogrammer/spring-lemon/wiki/Getting-Started-With-Spring-Lemon) on how to use it. 1. _[Example reactive microservices](https://github.com/naturalprogrammer/np-microservices-sample-02) using Spring Lemon, and its [configuration repo](https://github.com/naturalprogrammer/np-microservices-sample-02-config)_ — A sample reactive microservices application depicting how easy it is to develop reactive microservices using Spring Lemon. -1. _[Spring Framework Recipes For Real World Application Development](https://www.naturalprogrammer.com/p/spring-framework-book-of-best-practices)_ — a live book discussing key real-world topics on developing Spring applications, APIs and microservoces. Includes key Spring Lemon topics. [Click here](https://www.naturalprogrammer.com/p/spring-framework-book-of-best-practices) to get it now for FREE! +1. _[Spring Framework Recipes For Real World Application Development](https://www.naturalprogrammer.com/p/spring-framework-book-of-best-practices)_ — a live book discussing key real-world topics on developing Spring applications, APIs and microservoces. Includes many Spring Lemon topics. [Click here](https://www.naturalprogrammer.com/p/spring-framework-book-of-best-practices) to get it now for FREE! 1. Video tutorials coming soon: 1. Spring Framework 5 REST API Development — A Complete Blueprint For Real-World Developers 1. Spring WebFlux Reactive REST API Development — A Complete Blueprint For Real-World Developers From 0451e6c5719ab3dcea0de1792671912a6d475aaf Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Sat, 11 Aug 2018 07:22:58 +0530 Subject: [PATCH 044/116] Updated README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 2cbcfc7e..de02bdd6 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Spring Lemon -> Minimize your development cost with our intensive consulting/training on Spring — [click here](https://www.naturalprogrammer.com/) for details. +> Minimize your development cost with our intensive consulting/training — [click here](https://www.naturalprogrammer.com/) for details. When developing **real-world** Spring REST APIs and microservices, you face many challenges like From b7fbaa338ecdc1439e56d6fd80e309aff81bc128 Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Sun, 12 Aug 2018 17:47:43 +0530 Subject: [PATCH 045/116] Isolated authorizeExchnage so that it can be overridden --- lemon-demo-jpa/pom.xml | 2 +- lemon-demo-reactive/pom.xml | 2 +- pom.xml | 2 +- spring-lemon-commons-reactive/pom.xml | 2 +- .../LemonCommonsReactiveSecurityConfig.java | 27 ++++++++++++------- spring-lemon-commons/pom.xml | 2 +- spring-lemon-exceptions/pom.xml | 2 +- spring-lemon-jpa/pom.xml | 2 +- spring-lemon-reactive/pom.xml | 2 +- .../LemonReactiveController.java | 2 +- .../security/LemonReactiveSecurityConfig.java | 11 ++++---- 11 files changed, 32 insertions(+), 24 deletions(-) diff --git a/lemon-demo-jpa/pom.xml b/lemon-demo-jpa/pom.xml index d29f7dbc..67e2982c 100644 --- a/lemon-demo-jpa/pom.xml +++ b/lemon-demo-jpa/pom.xml @@ -14,7 +14,7 @@ com.naturalprogrammer spring-lemon - 1.0.0.M6 + 1.0.0.M7 diff --git a/lemon-demo-reactive/pom.xml b/lemon-demo-reactive/pom.xml index 7b7648dd..9ecd26cf 100644 --- a/lemon-demo-reactive/pom.xml +++ b/lemon-demo-reactive/pom.xml @@ -13,7 +13,7 @@ com.naturalprogrammer spring-lemon - 1.0.0.M6 + 1.0.0.M7 diff --git a/pom.xml b/pom.xml index 9cb20b1b..c8fdca85 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.naturalprogrammer spring-lemon - 1.0.0.M6 + 1.0.0.M7 pom spring-lemon diff --git a/spring-lemon-commons-reactive/pom.xml b/spring-lemon-commons-reactive/pom.xml index 76248da1..8ade1524 100644 --- a/spring-lemon-commons-reactive/pom.xml +++ b/spring-lemon-commons-reactive/pom.xml @@ -13,7 +13,7 @@ com.naturalprogrammer spring-lemon - 1.0.0.M6 + 1.0.0.M7 diff --git a/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/security/LemonCommonsReactiveSecurityConfig.java b/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/security/LemonCommonsReactiveSecurityConfig.java index d88a359f..5b55212f 100644 --- a/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/security/LemonCommonsReactiveSecurityConfig.java +++ b/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/security/LemonCommonsReactiveSecurityConfig.java @@ -40,11 +40,11 @@ public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) log.info("Configuring SecurityWebFilterChain ..."); - return formLogin(http) - .authorizeExchange() - .anyExchange().permitAll() - .and() - .securityContextRepository(NoOpServerSecurityContextRepository.getInstance()) + formLogin(http); // Configure form login + authorizeExchange(http); // configure authorization + + return http + .securityContextRepository(NoOpServerSecurityContextRepository.getInstance()) .exceptionHandling() .accessDeniedHandler(accessDeniedHandler()) .authenticationEntryPoint(authenticationEntryPoint()) @@ -55,13 +55,22 @@ public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) .build(); } - /** - * Configure form login - only in the auth service + * Override this to configure authorization + */ + protected void authorizeExchange(ServerHttpSecurity http) { + + http.authorizeExchange() + .anyExchange().permitAll(); + } + + + /** + * Configures form login */ - protected ServerHttpSecurity formLogin(ServerHttpSecurity http) { + protected void formLogin(ServerHttpSecurity http) { - return http; + // Bypass here. Form login is needed only in the auth service } diff --git a/spring-lemon-commons/pom.xml b/spring-lemon-commons/pom.xml index 55c6c797..636df9bf 100644 --- a/spring-lemon-commons/pom.xml +++ b/spring-lemon-commons/pom.xml @@ -14,7 +14,7 @@ com.naturalprogrammer spring-lemon - 1.0.0.M6 + 1.0.0.M7 diff --git a/spring-lemon-exceptions/pom.xml b/spring-lemon-exceptions/pom.xml index 205cdfd0..5c739a62 100644 --- a/spring-lemon-exceptions/pom.xml +++ b/spring-lemon-exceptions/pom.xml @@ -13,7 +13,7 @@ com.naturalprogrammer spring-lemon - 1.0.0.M6 + 1.0.0.M7 diff --git a/spring-lemon-jpa/pom.xml b/spring-lemon-jpa/pom.xml index 009ae5ef..14227ee3 100644 --- a/spring-lemon-jpa/pom.xml +++ b/spring-lemon-jpa/pom.xml @@ -13,7 +13,7 @@ com.naturalprogrammer spring-lemon - 1.0.0.M6 + 1.0.0.M7 diff --git a/spring-lemon-reactive/pom.xml b/spring-lemon-reactive/pom.xml index 581d3e6f..e264c649 100644 --- a/spring-lemon-reactive/pom.xml +++ b/spring-lemon-reactive/pom.xml @@ -13,7 +13,7 @@ com.naturalprogrammer spring-lemon - 1.0.0.M6 + 1.0.0.M7 diff --git a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveController.java b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveController.java index 10cd352c..d645f294 100644 --- a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveController.java +++ b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveController.java @@ -69,7 +69,7 @@ public void createLemonController( /** - * A simple function for pinging this server. + * Afgter a successful login, returns the current user with an authorization header. */ @PostMapping("/login") public Mono login(ServerWebExchange exchange) { diff --git a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/security/LemonReactiveSecurityConfig.java b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/security/LemonReactiveSecurityConfig.java index c26e9dbc..e6d96e71 100644 --- a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/security/LemonReactiveSecurityConfig.java +++ b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/security/LemonReactiveSecurityConfig.java @@ -35,13 +35,12 @@ public LemonReactiveSecurityConfig(JwtService jwtService, * Configure form login */ @Override - protected ServerHttpSecurity formLogin(ServerHttpSecurity http) { + protected void formLogin(ServerHttpSecurity http) { - return http.formLogin() - .loginPage(loginPage()) // Should be "/login" by default, but not providing that overwrites our AuthenticationFailureHandler, because this is called later - .authenticationFailureHandler(authenticationFailureHandler()) - .authenticationSuccessHandler(new WebFilterChainServerAuthenticationSuccessHandler()) - .and(); + http.formLogin() + .loginPage(loginPage()) // Should be "/login" by default, but not providing that overwrites our AuthenticationFailureHandler, because this is called later + .authenticationFailureHandler(authenticationFailureHandler()) + .authenticationSuccessHandler(new WebFilterChainServerAuthenticationSuccessHandler()); } /** From 60b6896e3e30dbadb63f778218e6298e06e2611a Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Mon, 13 Aug 2018 12:48:13 +0530 Subject: [PATCH 046/116] Updated README --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index de02bdd6..fc06ced8 100644 --- a/README.md +++ b/README.md @@ -33,7 +33,7 @@ Watch [this video tutorial](https://www.naturalprogrammer.com/p/spring-lemon-res 1. _Getting started guide_ 1. [Book](https://github.com/naturalprogrammer/spring-lemon/wiki/Getting-Started-With-Spring-Lemon) 1. [Video Tutorial](https://www.naturalprogrammer.com/p/spring-lemon-restful-web-services-development) -1. _[Example application](https://github.com/naturalprogrammer/spring-lemon/tree/master/lemon-demo-jpa)_ — A sample application using Spring Lemon. Quite similar to the one developed in the above [getting started guide](https://github.com/naturalprogrammer/spring-lemon/wiki/Getting-Started-With-Spring-Lemon), but additionally has automated tests. +1. _Example applications_ — [Non-reactive](https://github.com/naturalprogrammer/spring-lemon/tree/master/lemon-demo-jpa) and [reactive](https://github.com/naturalprogrammer/spring-lemon/tree/master/lemon-demo-reactive) sample applications using Spring Lemon. Quite similar to the one developed in the above [getting started guide](https://github.com/naturalprogrammer/spring-lemon/wiki/Getting-Started-With-Spring-Lemon), but additionally have automated tests. 1. _[API documentation](https://documenter.getpostman.com/view/305915/RVu2mqEH)_ of the above application. 1. _[Example AngularJS front-end application](https://github.com/naturalprogrammer/spring-lemon/tree/master/lemon-demo-angularjs)_ — A sample AngularJS 1.x front-end. It'll work both for the application developed in the above [getting started guide](https://github.com/naturalprogrammer/spring-lemon/wiki/Getting-Started-With-Spring-Lemon) as well as the [Lemon Demo application](https://github.com/naturalprogrammer/spring-lemon/tree/master/lemon-demo-jpa). See the [Getting Started Guide](https://github.com/naturalprogrammer/spring-lemon/wiki/Getting-Started-With-Spring-Lemon) on how to use it. 1. _[Example reactive microservices](https://github.com/naturalprogrammer/np-microservices-sample-02) using Spring Lemon, and its [configuration repo](https://github.com/naturalprogrammer/np-microservices-sample-02-config)_ — A sample reactive microservices application depicting how easy it is to develop reactive microservices using Spring Lemon. @@ -41,8 +41,8 @@ Watch [this video tutorial](https://www.naturalprogrammer.com/p/spring-lemon-res 1. Video tutorials coming soon: 1. Spring Framework 5 REST API Development — A Complete Blueprint For Real-World Developers 1. Spring WebFlux Reactive REST API Development — A Complete Blueprint For Real-World Developers - 1. Real World Microservices Using Spring Cloud — A Rapid Course - 1. Join [here](https://www.naturalprogrammer.com/p/spring-framework-book-of-best-practices) to get notified when the above courses get released + 1. Microservices Using Spring Cloud — A Rapid Course For Real World Developers + 1. Join [here](https://www.naturalprogrammer.com/p/spring-framework-book-of-best-practices) to get notified and avail heavy discounts when the above courses get released ## Help and Support 1. Community help is available at [stackoverflow.com](http://stackoverflow.com/questions/tagged/spring-lemon), under the `spring-lemon` tag. Do not miss to tag the questions with `spring-lemon`! From ee461b867b3c913809be7090a5f44d44f88e4c02 Mon Sep 17 00:00:00 2001 From: skpat Date: Fri, 31 Aug 2018 11:57:27 +0530 Subject: [PATCH 047/116] Lemon Demo JPA now uses PostgreSQL instead of MySQL --- lemon-demo-jpa/pom.xml | 6 +++--- .../src/main/resources/config/application-dev.yml | 4 +++- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/lemon-demo-jpa/pom.xml b/lemon-demo-jpa/pom.xml index 67e2982c..14a2d344 100644 --- a/lemon-demo-jpa/pom.xml +++ b/lemon-demo-jpa/pom.xml @@ -30,10 +30,10 @@ runtime + - mysql - mysql-connector-java - runtime + org.postgresql + postgresql diff --git a/lemon-demo-jpa/src/main/resources/config/application-dev.yml b/lemon-demo-jpa/src/main/resources/config/application-dev.yml index ecab5f86..b17b46ca 100644 --- a/lemon-demo-jpa/src/main/resources/config/application-dev.yml +++ b/lemon-demo-jpa/src/main/resources/config/application-dev.yml @@ -5,8 +5,10 @@ spring: jpa: hibernate: use-new-id-generator-mappings: false + properties: + hibernate.jdbc.lob.non_contextual_creation: true datasource: - url: jdbc:mysql://localhost:3306/lemon?useSSL=false + url: jdbc:postgresql://localhost:5432/lemondb username: lemon password: lemon security: From d07bdb00bf8c3d60c0b2c78e6fc48f5ac2ebcaff Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Mon, 24 Sep 2018 21:53:00 +0530 Subject: [PATCH 048/116] Midway creating the spring-lemon-commons-web module --- .../spring/lemondemo/MySecurityConfig.java | 4 +- pom.xml | 8 +- .../LemonCommonsReactiveSecurityConfig.java | 13 +- spring-lemon-commons-web/pom.xml | 40 +++ .../LemonCommonsWebAutoConfiguration.java | 26 ++ ...faultExceptionHandlerControllerAdvice.java | 4 +- .../exceptions/LemonErrorAttributes.java | 3 +- .../exceptions/LemonErrorController.java | 2 +- .../security/JwtAuthenticationProvider.java | 68 ++++++ .../commonsweb}/security/LemonCorsConfig.java | 2 +- .../security/LemonSecurityConfig.java | 7 +- .../LemonTokenAuthenticationFilter.java | 2 +- .../lemon/commonsweb/util/LecwUtils.java | 25 ++ .../main/resources/META-INF/spring.factories | 2 + .../spring/lemon/commons/util/LecUtils.java | 13 + spring-lemon-jpa/pom.xml | 7 +- .../spring/lemon/LemonAutoConfiguration.java | 29 ++- ...eOAuth2AuthorizationRequestRepository.java | 4 +- ...java => JpaJwtAuthenticationProvider.java} | 33 +-- .../security/LemonJpaSecurityConfig.java | 231 ++++++++++++++++++ .../OAuth2AuthenticationSuccessHandler.java | 3 +- .../spring/lemon/util/LemonUtils.java | 20 -- 22 files changed, 451 insertions(+), 95 deletions(-) create mode 100644 spring-lemon-commons-web/pom.xml create mode 100644 spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/LemonCommonsWebAutoConfiguration.java rename {spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon => spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb}/exceptions/DefaultExceptionHandlerControllerAdvice.java (86%) rename {spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon => spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb}/exceptions/LemonErrorAttributes.java (91%) rename {spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon => spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb}/exceptions/LemonErrorController.java (94%) create mode 100644 spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/security/JwtAuthenticationProvider.java rename {spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon => spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb}/security/LemonCorsConfig.java (91%) rename {spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon => spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb}/security/LemonSecurityConfig.java (93%) rename {spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon => spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb}/security/LemonTokenAuthenticationFilter.java (94%) create mode 100644 spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/util/LecwUtils.java create mode 100644 spring-lemon-commons-web/src/main/resources/META-INF/spring.factories rename spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/{JwtAuthenticationProvider.java => JpaJwtAuthenticationProvider.java} (55%) create mode 100644 spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonJpaSecurityConfig.java diff --git a/lemon-demo-jpa/src/main/java/com/naturalprogrammer/spring/lemondemo/MySecurityConfig.java b/lemon-demo-jpa/src/main/java/com/naturalprogrammer/spring/lemondemo/MySecurityConfig.java index effea0aa..e9621817 100644 --- a/lemon-demo-jpa/src/main/java/com/naturalprogrammer/spring/lemondemo/MySecurityConfig.java +++ b/lemon-demo-jpa/src/main/java/com/naturalprogrammer/spring/lemondemo/MySecurityConfig.java @@ -5,10 +5,10 @@ import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.stereotype.Component; -import com.naturalprogrammer.spring.lemon.security.LemonSecurityConfig; +import com.naturalprogrammer.spring.lemon.security.LemonJpaSecurityConfig; @Component -public class MySecurityConfig extends LemonSecurityConfig { +public class MySecurityConfig extends LemonJpaSecurityConfig { private static final Log log = LogFactory.getLog(MySecurityConfig.class); diff --git a/pom.xml b/pom.xml index c8fdca85..63ec868d 100644 --- a/pom.xml +++ b/pom.xml @@ -22,6 +22,7 @@ spring-lemon-exceptions spring-lemon-commons + spring-lemon-commons-web spring-lemon-commons-reactive spring-lemon-jpa spring-lemon-reactive @@ -80,13 +81,6 @@ - - - jitpack.io - https://jitpack.io - - - UTF-8 UTF-8 diff --git a/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/security/LemonCommonsReactiveSecurityConfig.java b/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/security/LemonCommonsReactiveSecurityConfig.java index 5b55212f..2371c6dd 100644 --- a/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/security/LemonCommonsReactiveSecurityConfig.java +++ b/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/security/LemonCommonsReactiveSecurityConfig.java @@ -93,7 +93,7 @@ protected ReactiveAuthenticationManager tokenAuthenticationManager() { JWTClaimsSet claims = jwtService.parseToken(token, JwtService.AUTH_AUDIENCE); - UserDto userDto = getUserDto(claims); + UserDto userDto = LecUtils.getUserDto(claims); Mono userDtoMono = userDto == null ? fetchUserDto(claims) : Mono.just(userDto); @@ -115,17 +115,6 @@ protected Mono fetchUserDto(JWTClaimsSet claims) { LexUtils.getMessage("com.naturalprogrammer.spring.userClaimAbsent"))); } - protected UserDto getUserDto(JWTClaimsSet claims) { - - Object userClaim = claims.getClaim(JwtService.USER_CLAIM); - - if (userClaim == null) - return null; - - return LecUtils.deserialize((String) userClaim); - } - - protected Function> tokenAuthenticationConverter() { return serverWebExchange -> { diff --git a/spring-lemon-commons-web/pom.xml b/spring-lemon-commons-web/pom.xml new file mode 100644 index 00000000..53e9d10a --- /dev/null +++ b/spring-lemon-commons-web/pom.xml @@ -0,0 +1,40 @@ + + + 4.0.0 + + com.naturalprogrammer.spring-lemon + spring-lemon-commons-web + jar + + spring-lemon-commons-web + >Helper commons web library for Spring Boot REST APIs + + + com.naturalprogrammer + spring-lemon + 1.0.0.M7 + + + + + + com.naturalprogrammer.spring-lemon + spring-lemon-commons + ${project.version} + + + + org.springframework.boot + spring-boot-starter-web + + + + org.springframework.boot + spring-boot-starter-test + test + + + + + diff --git a/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/LemonCommonsWebAutoConfiguration.java b/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/LemonCommonsWebAutoConfiguration.java new file mode 100644 index 00000000..08e65c51 --- /dev/null +++ b/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/LemonCommonsWebAutoConfiguration.java @@ -0,0 +1,26 @@ +package com.naturalprogrammer.spring.lemon.commonsweb; + +import org.springframework.boot.autoconfigure.AutoConfigureBefore; +import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration; +import org.springframework.boot.autoconfigure.security.servlet.SecurityFilterAutoConfiguration; +import org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration; +import org.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConfiguration; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.web.config.EnableSpringDataWebSupport; +import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; + +import com.naturalprogrammer.spring.lemon.commons.LemonCommonsAutoConfiguration; + +@Configuration +@EnableSpringDataWebSupport +@EnableGlobalMethodSecurity(prePostEnabled = true) +@AutoConfigureBefore({ + WebMvcAutoConfiguration.class, + ErrorMvcAutoConfiguration.class, + SecurityAutoConfiguration.class, + SecurityFilterAutoConfiguration.class, + LemonCommonsAutoConfiguration.class}) +public class LemonCommonsWebAutoConfiguration { + + +} diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/DefaultExceptionHandlerControllerAdvice.java b/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/exceptions/DefaultExceptionHandlerControllerAdvice.java similarity index 86% rename from spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/DefaultExceptionHandlerControllerAdvice.java rename to spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/exceptions/DefaultExceptionHandlerControllerAdvice.java index e92c427a..64bd53ec 100644 --- a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/DefaultExceptionHandlerControllerAdvice.java +++ b/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/exceptions/DefaultExceptionHandlerControllerAdvice.java @@ -1,4 +1,4 @@ -package com.naturalprogrammer.spring.lemon.exceptions; +package com.naturalprogrammer.spring.lemon.commonsweb.exceptions; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -8,6 +8,8 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestControllerAdvice; +import com.naturalprogrammer.spring.lemon.exceptions.ErrorResponse; +import com.naturalprogrammer.spring.lemon.exceptions.ErrorResponseComposer; import com.naturalprogrammer.spring.lemon.exceptions.util.LexUtils; /** diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/LemonErrorAttributes.java b/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/exceptions/LemonErrorAttributes.java similarity index 91% rename from spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/LemonErrorAttributes.java rename to spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/exceptions/LemonErrorAttributes.java index 72936698..c27cd5c7 100644 --- a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/LemonErrorAttributes.java +++ b/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/exceptions/LemonErrorAttributes.java @@ -1,4 +1,4 @@ -package com.naturalprogrammer.spring.lemon.exceptions; +package com.naturalprogrammer.spring.lemon.commonsweb.exceptions; import java.util.Map; @@ -7,6 +7,7 @@ import org.springframework.boot.web.servlet.error.DefaultErrorAttributes; import org.springframework.web.context.request.WebRequest; +import com.naturalprogrammer.spring.lemon.exceptions.ErrorResponseComposer; import com.naturalprogrammer.spring.lemon.exceptions.util.LexUtils; /** diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/LemonErrorController.java b/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/exceptions/LemonErrorController.java similarity index 94% rename from spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/LemonErrorController.java rename to spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/exceptions/LemonErrorController.java index 8e1e91b7..9894044c 100644 --- a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/LemonErrorController.java +++ b/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/exceptions/LemonErrorController.java @@ -1,4 +1,4 @@ -package com.naturalprogrammer.spring.lemon.exceptions; +package com.naturalprogrammer.spring.lemon.commonsweb.exceptions; import java.util.List; import java.util.Map; diff --git a/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/security/JwtAuthenticationProvider.java b/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/security/JwtAuthenticationProvider.java new file mode 100644 index 00000000..b63b8f2a --- /dev/null +++ b/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/security/JwtAuthenticationProvider.java @@ -0,0 +1,68 @@ +package com.naturalprogrammer.spring.lemon.commonsweb.security; + +import java.io.Serializable; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.springframework.security.authentication.AuthenticationCredentialsNotFoundException; +import org.springframework.security.authentication.AuthenticationProvider; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.userdetails.UsernameNotFoundException; + +import com.naturalprogrammer.spring.lemon.commons.security.JwtAuthenticationToken; +import com.naturalprogrammer.spring.lemon.commons.security.JwtService; +import com.naturalprogrammer.spring.lemon.commons.security.LemonPrincipal; +import com.naturalprogrammer.spring.lemon.commons.security.UserDto; +import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; +import com.naturalprogrammer.spring.lemon.exceptions.util.LexUtils; +import com.nimbusds.jwt.JWTClaimsSet; + +/** + * Authentication provider for JWT token authentication + */ +public class JwtAuthenticationProvider implements AuthenticationProvider { + + private static final Log log = LogFactory.getLog(JwtAuthenticationProvider.class); + + private final JwtService jwtService; + + public JwtAuthenticationProvider(JwtService jwtService) { + + this.jwtService = jwtService; + log.debug("Created"); + } + + @Override + public Authentication authenticate(Authentication auth) { + + log.debug("Authenticating ..."); + + String token = (String) auth.getCredentials(); + + JWTClaimsSet claims = jwtService.parseToken(token, JwtService.AUTH_AUDIENCE); + UserDto userDto = LecUtils.getUserDto(claims); + if (userDto == null) + userDto = fetchUserDto(claims); + + LemonPrincipal principal = new LemonPrincipal(userDto); + + return new JwtAuthenticationToken(principal, token, principal.getAuthorities()); + } + + /** + * Default behaviour is to throw error. To be overridden in auth service. + * + * @param username + * @return + */ + protected UserDto fetchUserDto(JWTClaimsSet claims) { + throw new AuthenticationCredentialsNotFoundException( + LexUtils.getMessage("com.naturalprogrammer.spring.userClaimAbsent")); + } + + @Override + public boolean supports(Class authentication) { + + return (JwtAuthenticationToken.class.isAssignableFrom(authentication)); + } +} diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonCorsConfig.java b/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/security/LemonCorsConfig.java similarity index 91% rename from spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonCorsConfig.java rename to spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/security/LemonCorsConfig.java index d4fc7067..4eb0cce2 100644 --- a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonCorsConfig.java +++ b/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/security/LemonCorsConfig.java @@ -1,4 +1,4 @@ -package com.naturalprogrammer.spring.lemon.security; +package com.naturalprogrammer.spring.lemon.commonsweb.security; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonSecurityConfig.java b/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/security/LemonSecurityConfig.java similarity index 93% rename from spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonSecurityConfig.java rename to spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/security/LemonSecurityConfig.java index f0cd5116..1b94a11f 100644 --- a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonSecurityConfig.java +++ b/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/security/LemonSecurityConfig.java @@ -1,4 +1,4 @@ -package com.naturalprogrammer.spring.lemon.security; +package com.naturalprogrammer.spring.lemon.commonsweb.security; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -14,6 +14,7 @@ import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; import com.naturalprogrammer.spring.lemon.commons.LemonProperties; +import com.naturalprogrammer.spring.lemon.commonsweb.security.LemonTokenAuthenticationFilter; /** * Security configuration class. Extend it in the @@ -34,7 +35,7 @@ public class LemonSecurityConfig extends WebSecurityConfigurerAdapter { private LemonOAuth2UserService oauth2UserService; private OAuth2AuthenticationSuccessHandler oauth2AuthenticationSuccessHandler; private OAuth2AuthenticationFailureHandler oauth2AuthenticationFailureHandler; - private JwtAuthenticationProvider jwtAuthenticationProvider; + private JpaJwtAuthenticationProvider jwtAuthenticationProvider; private PasswordEncoder passwordEncoder; @Autowired @@ -44,7 +45,7 @@ public void createLemonSecurityConfig(LemonProperties properties, UserDetailsSer LemonOAuth2UserService oauth2UserService, OAuth2AuthenticationSuccessHandler oauth2AuthenticationSuccessHandler, OAuth2AuthenticationFailureHandler oauth2AuthenticationFailureHandler, - JwtAuthenticationProvider jwtAuthenticationProvider, + JpaJwtAuthenticationProvider jwtAuthenticationProvider, PasswordEncoder passwordEncoder ) { diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonTokenAuthenticationFilter.java b/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/security/LemonTokenAuthenticationFilter.java similarity index 94% rename from spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonTokenAuthenticationFilter.java rename to spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/security/LemonTokenAuthenticationFilter.java index 38ffe11f..701cab21 100644 --- a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonTokenAuthenticationFilter.java +++ b/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/security/LemonTokenAuthenticationFilter.java @@ -1,4 +1,4 @@ -package com.naturalprogrammer.spring.lemon.security; +package com.naturalprogrammer.spring.lemon.commonsweb.security; import java.io.IOException; diff --git a/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/util/LecwUtils.java b/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/util/LecwUtils.java new file mode 100644 index 00000000..0293068b --- /dev/null +++ b/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/util/LecwUtils.java @@ -0,0 +1,25 @@ +package com.naturalprogrammer.spring.lemon.commonsweb.util; + +import java.util.Optional; + +import javax.servlet.http.Cookie; +import javax.servlet.http.HttpServletRequest; + +public class LecwUtils { + + /** + * Fetches a cookie from the request + */ + public static Optional fetchCookie(HttpServletRequest request, String name) { + + Cookie[] cookies = request.getCookies(); + + if (cookies != null && cookies.length > 0) + for (int i = 0; i < cookies.length; i++) + if (cookies[i].getName().equals(name)) + return Optional.of(cookies[i]); + + return Optional.empty(); + } + +} diff --git a/spring-lemon-commons-web/src/main/resources/META-INF/spring.factories b/spring-lemon-commons-web/src/main/resources/META-INF/spring.factories new file mode 100644 index 00000000..3c7dad2e --- /dev/null +++ b/spring-lemon-commons-web/src/main/resources/META-INF/spring.factories @@ -0,0 +1,2 @@ +org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ +com.naturalprogrammer.spring.lemon.commonsweb.LemonCommonsWebAutoConfiguration \ No newline at end of file diff --git a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/util/LecUtils.java b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/util/LecUtils.java index 7911ba5e..3d4ad601 100644 --- a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/util/LecUtils.java +++ b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/util/LecUtils.java @@ -25,9 +25,11 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.github.fge.jsonpatch.JsonPatch; import com.github.fge.jsonpatch.JsonPatchException; +import com.naturalprogrammer.spring.lemon.commons.security.JwtService; import com.naturalprogrammer.spring.lemon.commons.security.LemonPrincipal; import com.naturalprogrammer.spring.lemon.commons.security.UserDto; import com.naturalprogrammer.spring.lemon.exceptions.util.LexUtils; +import com.nimbusds.jwt.JWTClaimsSet; /** * Useful helper methods @@ -249,4 +251,15 @@ public static T deserialize(String serializedObj) { return SerializationUtils.deserialize( Base64.getUrlDecoder().decode(serializedObj)); } + + + public static UserDto getUserDto(JWTClaimsSet claims) { + + Object userClaim = claims.getClaim(JwtService.USER_CLAIM); + + if (userClaim == null) + return null; + + return LecUtils.deserialize((String) userClaim); + } } diff --git a/spring-lemon-jpa/pom.xml b/spring-lemon-jpa/pom.xml index 14227ee3..40fcfa08 100644 --- a/spring-lemon-jpa/pom.xml +++ b/spring-lemon-jpa/pom.xml @@ -20,7 +20,7 @@ com.naturalprogrammer.spring-lemon - spring-lemon-commons + spring-lemon-commons-web ${project.version} @@ -29,11 +29,6 @@ spring-boot-starter-data-jpa - - org.springframework.boot - spring-boot-starter-web - - javax.xml.bind jaxb-api diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/LemonAutoConfiguration.java b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/LemonAutoConfiguration.java index 8bbbaf73..6c79bc91 100644 --- a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/LemonAutoConfiguration.java +++ b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/LemonAutoConfiguration.java @@ -37,19 +37,20 @@ import com.naturalprogrammer.spring.lemon.commons.security.JwtService; import com.naturalprogrammer.spring.lemon.commons.validation.CaptchaValidator; import com.naturalprogrammer.spring.lemon.commons.validation.RetypePasswordValidator; +import com.naturalprogrammer.spring.lemon.commonsweb.LemonCommonsWebAutoConfiguration; +import com.naturalprogrammer.spring.lemon.commonsweb.exceptions.DefaultExceptionHandlerControllerAdvice; +import com.naturalprogrammer.spring.lemon.commonsweb.exceptions.LemonErrorAttributes; +import com.naturalprogrammer.spring.lemon.commonsweb.exceptions.LemonErrorController; +import com.naturalprogrammer.spring.lemon.commonsweb.security.LemonCorsConfig; import com.naturalprogrammer.spring.lemon.domain.AbstractUser; import com.naturalprogrammer.spring.lemon.domain.AbstractUserRepository; import com.naturalprogrammer.spring.lemon.domain.LemonAuditorAware; -import com.naturalprogrammer.spring.lemon.exceptions.DefaultExceptionHandlerControllerAdvice; import com.naturalprogrammer.spring.lemon.exceptions.ErrorResponseComposer; -import com.naturalprogrammer.spring.lemon.exceptions.LemonErrorAttributes; -import com.naturalprogrammer.spring.lemon.exceptions.LemonErrorController; -import com.naturalprogrammer.spring.lemon.security.JwtAuthenticationProvider; +import com.naturalprogrammer.spring.lemon.security.JpaJwtAuthenticationProvider; import com.naturalprogrammer.spring.lemon.security.LemonAuthenticationSuccessHandler; -import com.naturalprogrammer.spring.lemon.security.LemonCorsConfig; import com.naturalprogrammer.spring.lemon.security.LemonOAuth2UserService; import com.naturalprogrammer.spring.lemon.security.LemonOidcUserService; -import com.naturalprogrammer.spring.lemon.security.LemonSecurityConfig; +import com.naturalprogrammer.spring.lemon.security.LemonJpaSecurityConfig; import com.naturalprogrammer.spring.lemon.security.LemonUserDetailsService; import com.naturalprogrammer.spring.lemon.security.OAuth2AuthenticationFailureHandler; import com.naturalprogrammer.spring.lemon.security.OAuth2AuthenticationSuccessHandler; @@ -62,16 +63,14 @@ * @author Sanjay Patel */ @Configuration -@EnableSpringDataWebSupport @EnableTransactionManagement @EnableJpaAuditing -@EnableGlobalMethodSecurity(prePostEnabled = true) @AutoConfigureBefore({ WebMvcAutoConfiguration.class, ErrorMvcAutoConfiguration.class, SecurityAutoConfiguration.class, SecurityFilterAutoConfiguration.class, - LemonCommonsAutoConfiguration.class}) + LemonCommonsWebAutoConfiguration.class}) public class LemonAutoConfiguration { /** @@ -255,25 +254,25 @@ LemonOAuth2UserService lemonOAuth2UserService( * Configures JwtAuthenticationProvider if missing */ @Bean - @ConditionalOnMissingBean(JwtAuthenticationProvider.class) + @ConditionalOnMissingBean(JpaJwtAuthenticationProvider.class) public , ID extends Serializable> - JwtAuthenticationProvider jwtAuthenticationProvider( + JpaJwtAuthenticationProvider jwtAuthenticationProvider( JwtService jwtService, LemonUserDetailsService userDetailsService) { log.info("Configuring JwtAuthenticationProvider"); - return new JwtAuthenticationProvider(jwtService, userDetailsService); + return new JpaJwtAuthenticationProvider(jwtService, userDetailsService); } /** * Configures LemonSecurityConfig if missing */ @Bean - @ConditionalOnMissingBean(LemonSecurityConfig.class) - public LemonSecurityConfig lemonSecurityConfig() { + @ConditionalOnMissingBean(LemonJpaSecurityConfig.class) + public LemonJpaSecurityConfig lemonSecurityConfig() { log.info("Configuring LemonSecurityConfig"); - return new LemonSecurityConfig(); + return new LemonJpaSecurityConfig(); } /** diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/HttpCookieOAuth2AuthorizationRequestRepository.java b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/HttpCookieOAuth2AuthorizationRequestRepository.java index 70b1946d..c3f7cb78 100644 --- a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/HttpCookieOAuth2AuthorizationRequestRepository.java +++ b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/HttpCookieOAuth2AuthorizationRequestRepository.java @@ -11,7 +11,7 @@ import com.naturalprogrammer.spring.lemon.commons.LemonProperties; import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; -import com.naturalprogrammer.spring.lemon.util.LemonUtils; +import com.naturalprogrammer.spring.lemon.commonsweb.util.LecwUtils; /** * Cookie based repository for storing Authorization requests @@ -36,7 +36,7 @@ public OAuth2AuthorizationRequest loadAuthorizationRequest(HttpServletRequest re Assert.notNull(request, "request cannot be null"); - return LemonUtils.fetchCookie(request, AUTHORIZATION_REQUEST_COOKIE_NAME) + return LecwUtils.fetchCookie(request, AUTHORIZATION_REQUEST_COOKIE_NAME) .map(this::deserialize) .orElse(null); } diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/JwtAuthenticationProvider.java b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/JpaJwtAuthenticationProvider.java similarity index 55% rename from spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/JwtAuthenticationProvider.java rename to spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/JpaJwtAuthenticationProvider.java index c0b3258d..2396467e 100644 --- a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/JwtAuthenticationProvider.java +++ b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/JpaJwtAuthenticationProvider.java @@ -4,6 +4,7 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.springframework.security.authentication.AuthenticationCredentialsNotFoundException; import org.springframework.security.authentication.AuthenticationProvider; import org.springframework.security.core.Authentication; import org.springframework.security.core.userdetails.UsernameNotFoundException; @@ -11,37 +12,33 @@ import com.naturalprogrammer.spring.lemon.commons.security.JwtAuthenticationToken; import com.naturalprogrammer.spring.lemon.commons.security.JwtService; import com.naturalprogrammer.spring.lemon.commons.security.LemonPrincipal; +import com.naturalprogrammer.spring.lemon.commons.security.UserDto; +import com.naturalprogrammer.spring.lemon.commonsweb.security.JwtAuthenticationProvider; import com.naturalprogrammer.spring.lemon.domain.AbstractUser; +import com.naturalprogrammer.spring.lemon.exceptions.util.LexUtils; import com.naturalprogrammer.spring.lemon.util.LemonUtils; import com.nimbusds.jwt.JWTClaimsSet; /** * Authentication provider for JWT token authentication */ -public class JwtAuthenticationProvider -, ID extends Serializable> implements AuthenticationProvider { +public class JpaJwtAuthenticationProvider +, ID extends Serializable> extends JwtAuthenticationProvider { - private static final Log log = LogFactory.getLog(JwtAuthenticationProvider.class); + private static final Log log = LogFactory.getLog(JpaJwtAuthenticationProvider.class); - private final JwtService jwtService; private LemonUserDetailsService userDetailsService; - public JwtAuthenticationProvider(JwtService jwtService, LemonUserDetailsService userDetailsService) { + public JpaJwtAuthenticationProvider(JwtService jwtService, LemonUserDetailsService userDetailsService) { - this.jwtService = jwtService; + super(jwtService); this.userDetailsService = userDetailsService; log.debug("Created"); } @Override - public Authentication authenticate(Authentication auth) { - - log.debug("Authenticating ..."); - - String token = (String) auth.getCredentials(); - - JWTClaimsSet claims = jwtService.parseToken(token, JwtService.AUTH_AUDIENCE); + protected UserDto fetchUserDto(JWTClaimsSet claims) { String username = claims.getSubject(); U user = userDetailsService.findUserByUsername(username) @@ -50,14 +47,6 @@ public Authentication authenticate(Authentication auth) { log.debug("User found ..."); LemonUtils.ensureCredentialsUpToDate(claims, user); - LemonPrincipal principal = new LemonPrincipal(user.toUserDto()); - - return new JwtAuthenticationToken(principal, token, principal.getAuthorities()); - } - - @Override - public boolean supports(Class authentication) { - - return (JwtAuthenticationToken.class.isAssignableFrom(authentication)); + return user.toUserDto(); } } diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonJpaSecurityConfig.java b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonJpaSecurityConfig.java new file mode 100644 index 00000000..fb616d5e --- /dev/null +++ b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonJpaSecurityConfig.java @@ -0,0 +1,231 @@ +package com.naturalprogrammer.spring.lemon.security; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +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.password.PasswordEncoder; +import org.springframework.security.web.authentication.AuthenticationFailureHandler; +import org.springframework.security.web.authentication.Http403ForbiddenEntryPoint; +import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; + +import com.naturalprogrammer.spring.lemon.commons.LemonProperties; +import com.naturalprogrammer.spring.lemon.commonsweb.security.LemonTokenAuthenticationFilter; + +/** + * Security configuration class. Extend it in the + * application, and make a configuration class. Override + * protected methods, if you need any customization. + * + * @author Sanjay Patel + */ +public class LemonJpaSecurityConfig extends WebSecurityConfigurerAdapter { + + private static final Log log = LogFactory.getLog(LemonJpaSecurityConfig.class); + + private LemonProperties properties; + private UserDetailsService userDetailsService; + private LemonAuthenticationSuccessHandler authenticationSuccessHandler; + private AuthenticationFailureHandler authenticationFailureHandler; + private LemonOidcUserService oidcUserService; + private LemonOAuth2UserService oauth2UserService; + private OAuth2AuthenticationSuccessHandler oauth2AuthenticationSuccessHandler; + private OAuth2AuthenticationFailureHandler oauth2AuthenticationFailureHandler; + private JpaJwtAuthenticationProvider jwtAuthenticationProvider; + private PasswordEncoder passwordEncoder; + + @Autowired + public void createLemonSecurityConfig(LemonProperties properties, UserDetailsService userDetailsService, + LemonAuthenticationSuccessHandler authenticationSuccessHandler, AuthenticationFailureHandler authenticationFailureHandler, + LemonOidcUserService oidcUserService, + LemonOAuth2UserService oauth2UserService, + OAuth2AuthenticationSuccessHandler oauth2AuthenticationSuccessHandler, + OAuth2AuthenticationFailureHandler oauth2AuthenticationFailureHandler, + JpaJwtAuthenticationProvider jwtAuthenticationProvider, + PasswordEncoder passwordEncoder + ) { + + this.properties = properties; + this.userDetailsService = userDetailsService; + this.authenticationSuccessHandler = authenticationSuccessHandler; + this.authenticationFailureHandler = authenticationFailureHandler; + this.oidcUserService = oidcUserService; + this.oauth2UserService = oauth2UserService; + this.oauth2AuthenticationSuccessHandler = oauth2AuthenticationSuccessHandler; + this.oauth2AuthenticationFailureHandler = oauth2AuthenticationFailureHandler; + this.jwtAuthenticationProvider = jwtAuthenticationProvider; + this.passwordEncoder = passwordEncoder; + + log.info("Created"); + } + + /** + * Security configuration, calling protected methods + */ + @Override + protected void configure(HttpSecurity http) throws Exception { + + sessionCreationPolicy(http); // set session creation policy + login(http); // authentication + logout(http); // logout related configuration + exceptionHandling(http); // exception handling + tokenAuthentication(http); // configure token authentication filter + csrf(http); // CSRF configuration + cors(http); // CORS configuration + oauth2Client(http); + authorizeRequests(http); // authorize requests + otherConfigurations(http); // override this to add more configurations + } + + + /** + * Configuring session creation policy + */ + protected void sessionCreationPolicy(HttpSecurity http) throws Exception { + + // No session + http.sessionManagement() + .sessionCreationPolicy(SessionCreationPolicy.STATELESS); + } + + + /** + * Configuring authentication. + */ + protected void login(HttpSecurity http) throws Exception { + + http + .formLogin() // form login + .loginPage(loginPage()) + + /****************************************** + * Setting a successUrl would redirect the user there. Instead, + * let's send 200 and the userDto along with an Authorization token. + *****************************************/ + .successHandler(authenticationSuccessHandler) + + /******************************************* + * Setting the failureUrl will redirect the user to + * that url if login fails. Instead, we need to send + * 401. So, let's set failureHandler instead. + *******************************************/ + .failureHandler(authenticationFailureHandler); + } + + + /** + * Override this to change login URL + * + * @return + */ + protected String loginPage() { + + return "/api/core/login"; + } + + /** + * Logout related configuration + */ + protected void logout(HttpSecurity http) throws Exception { + + http + .logout().disable(); // we are stateless; so /logout endpoint not needed + } + + + /** + * Configures exception-handling + */ + protected void exceptionHandling(HttpSecurity http) throws Exception { + + http + .exceptionHandling() + + /*********************************************** + * To prevent redirection to the login page + * when someone tries to access a restricted page + **********************************************/ + .authenticationEntryPoint(new Http403ForbiddenEntryPoint()); + } + + + /** + * Configuring token authentication filter + */ + protected void tokenAuthentication(HttpSecurity http) throws Exception { + + http.addFilterBefore(new LemonTokenAuthenticationFilter( + super.authenticationManager()), + UsernamePasswordAuthenticationFilter.class); + } + + + /** + * Disables CSRF. We are stateless. + */ + protected void csrf(HttpSecurity http) throws Exception { + + http + .csrf().disable(); + } + + + /** + * Configures CORS + */ + protected void cors(HttpSecurity http) throws Exception { + + http + .cors(); + } + + + private void oauth2Client(HttpSecurity http) throws Exception { + + http.oauth2Login() + .authorizationEndpoint() + .authorizationRequestRepository(new HttpCookieOAuth2AuthorizationRequestRepository(properties)).and() + .successHandler(oauth2AuthenticationSuccessHandler) + .failureHandler(oauth2AuthenticationFailureHandler) + .userInfoEndpoint() + .oidcUserService(oidcUserService) + .userService(oauth2UserService); + } + + + /** + * URL based authorization configuration. Override this if needed. + */ + protected void authorizeRequests(HttpSecurity http) throws Exception { + http.authorizeRequests() + .mvcMatchers("/**").permitAll(); + } + + + /** + * Override this to add more http configurations, + * such as more authentication methods. + * + * @param http + * @throws Exception + */ + protected void otherConfigurations(HttpSecurity http) throws Exception { + + } + + + /** + * Needed for configuring JwtAuthenticationProvider + */ + @Override + protected void configure(AuthenticationManagerBuilder auth) throws Exception { + + auth.userDetailsService(userDetailsService) + .passwordEncoder(passwordEncoder).and() + .authenticationProvider(jwtAuthenticationProvider); + } +} diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/OAuth2AuthenticationSuccessHandler.java b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/OAuth2AuthenticationSuccessHandler.java index e44e2789..ee67f148 100644 --- a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/OAuth2AuthenticationSuccessHandler.java +++ b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/OAuth2AuthenticationSuccessHandler.java @@ -13,6 +13,7 @@ import com.naturalprogrammer.spring.lemon.commons.LemonProperties; import com.naturalprogrammer.spring.lemon.commons.security.JwtService; import com.naturalprogrammer.spring.lemon.commons.security.UserDto; +import com.naturalprogrammer.spring.lemon.commonsweb.util.LecwUtils; import com.naturalprogrammer.spring.lemon.util.LemonUtils; /** @@ -48,7 +49,7 @@ protected String determineTargetUrl(HttpServletRequest request, currentUser.getUsername(), (long) properties.getJwt().getShortLivedMillis()); - String targetUrl = LemonUtils.fetchCookie(request, + String targetUrl = LecwUtils.fetchCookie(request, HttpCookieOAuth2AuthorizationRequestRepository.LEMON_REDIRECT_URI_COOKIE_PARAM_NAME) .map(Cookie::getValue) .orElse(properties.getOauth2AuthenticationSuccessUrl()); diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/util/LemonUtils.java b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/util/LemonUtils.java index 09f81b47..20b0b747 100644 --- a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/util/LemonUtils.java +++ b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/util/LemonUtils.java @@ -1,10 +1,6 @@ package com.naturalprogrammer.spring.lemon.util; import java.io.Serializable; -import java.util.Optional; - -import javax.servlet.http.Cookie; -import javax.servlet.http.HttpServletRequest; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -110,20 +106,4 @@ void ensureCredentialsUpToDate(JWTClaimsSet claims, U user) { LecUtils.ensureCredentials(issueTime >= user.getCredentialsUpdatedMillis(), "com.naturalprogrammer.spring.obsoleteToken"); } - - - /** - * Fetches a cookie from the request - */ - public static Optional fetchCookie(HttpServletRequest request, String name) { - - Cookie[] cookies = request.getCookies(); - - if (cookies != null && cookies.length > 0) - for (int i = 0; i < cookies.length; i++) - if (cookies[i].getName().equals(name)) - return Optional.of(cookies[i]); - - return Optional.empty(); - } } From 6117c0d781035d5b759cf3703a3979322a61a57f Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Thu, 27 Sep 2018 13:53:28 +0530 Subject: [PATCH 049/116] Segregated LemonSecurityConfig --- .../LemonCommonsWebSecurityConfig.java | 147 +++++++++++ .../security/LemonSecurityConfig.java | 231 ------------------ .../security/LemonJpaSecurityConfig.java | 111 +-------- 3 files changed, 154 insertions(+), 335 deletions(-) create mode 100644 spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/security/LemonCommonsWebSecurityConfig.java delete mode 100644 spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/security/LemonSecurityConfig.java diff --git a/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/security/LemonCommonsWebSecurityConfig.java b/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/security/LemonCommonsWebSecurityConfig.java new file mode 100644 index 00000000..955e0f49 --- /dev/null +++ b/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/security/LemonCommonsWebSecurityConfig.java @@ -0,0 +1,147 @@ +package com.naturalprogrammer.spring.lemon.commonsweb.security; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; +import org.springframework.security.config.http.SessionCreationPolicy; +import org.springframework.security.web.authentication.Http403ForbiddenEntryPoint; +import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; + +/** + * Security configuration class. Extend it in the + * application, and make a configuration class. Override + * protected methods, if you need any customization. + * + * @author Sanjay Patel + */ +public class LemonCommonsWebSecurityConfig extends WebSecurityConfigurerAdapter { + + private static final Log log = LogFactory.getLog(LemonCommonsWebSecurityConfig.class); + + private JwtAuthenticationProvider jwtAuthenticationProvider; + + @Autowired + public void createLemonCommonsWebSecurityConfig(JwtAuthenticationProvider jwtAuthenticationProvider) { + + this.jwtAuthenticationProvider = jwtAuthenticationProvider; + log.info("Created"); + } + + /** + * Security configuration, calling protected methods + */ + @Override + protected void configure(HttpSecurity http) throws Exception { + + sessionCreationPolicy(http); // set session creation policy + logout(http); // logout related configuration + exceptionHandling(http); // exception handling + tokenAuthentication(http); // configure token authentication filter + csrf(http); // CSRF configuration + cors(http); // CORS configuration + authorizeRequests(http); // authorize requests + otherConfigurations(http); // override this to add more configurations + } + + + /** + * Configuring session creation policy + */ + protected void sessionCreationPolicy(HttpSecurity http) throws Exception { + + // No session + http.sessionManagement() + .sessionCreationPolicy(SessionCreationPolicy.STATELESS); + } + + + /** + * Logout related configuration + */ + protected void logout(HttpSecurity http) throws Exception { + + http + .logout().disable(); // we are stateless; so /logout endpoint not needed + } + + + /** + * Configures exception-handling + */ + protected void exceptionHandling(HttpSecurity http) throws Exception { + + http + .exceptionHandling() + + /*********************************************** + * To prevent redirection to the login page + * when someone tries to access a restricted page + **********************************************/ + .authenticationEntryPoint(new Http403ForbiddenEntryPoint()); + } + + + /** + * Configuring token authentication filter + */ + protected void tokenAuthentication(HttpSecurity http) throws Exception { + + http.addFilterBefore(new LemonTokenAuthenticationFilter( + super.authenticationManager()), + UsernamePasswordAuthenticationFilter.class); + } + + + /** + * Disables CSRF. We are stateless. + */ + protected void csrf(HttpSecurity http) throws Exception { + + http + .csrf().disable(); + } + + + /** + * Configures CORS + */ + protected void cors(HttpSecurity http) throws Exception { + + http + .cors(); + } + + + /** + * URL based authorization configuration. Override this if needed. + */ + protected void authorizeRequests(HttpSecurity http) throws Exception { + http.authorizeRequests() + .mvcMatchers("/**").permitAll(); + } + + + /** + * Override this to add more http configurations, + * such as more authentication methods. + * + * @param http + * @throws Exception + */ + protected void otherConfigurations(HttpSecurity http) throws Exception { + + } + + + /** + * Needed for configuring JwtAuthenticationProvider + */ + @Override + protected void configure(AuthenticationManagerBuilder auth) throws Exception { + + auth.authenticationProvider(jwtAuthenticationProvider); + } +} diff --git a/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/security/LemonSecurityConfig.java b/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/security/LemonSecurityConfig.java deleted file mode 100644 index 1b94a11f..00000000 --- a/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/security/LemonSecurityConfig.java +++ /dev/null @@ -1,231 +0,0 @@ -package com.naturalprogrammer.spring.lemon.commonsweb.security; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; -import org.springframework.security.config.annotation.web.builders.HttpSecurity; -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.password.PasswordEncoder; -import org.springframework.security.web.authentication.AuthenticationFailureHandler; -import org.springframework.security.web.authentication.Http403ForbiddenEntryPoint; -import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; - -import com.naturalprogrammer.spring.lemon.commons.LemonProperties; -import com.naturalprogrammer.spring.lemon.commonsweb.security.LemonTokenAuthenticationFilter; - -/** - * Security configuration class. Extend it in the - * application, and make a configuration class. Override - * protected methods, if you need any customization. - * - * @author Sanjay Patel - */ -public class LemonSecurityConfig extends WebSecurityConfigurerAdapter { - - private static final Log log = LogFactory.getLog(LemonSecurityConfig.class); - - private LemonProperties properties; - private UserDetailsService userDetailsService; - private LemonAuthenticationSuccessHandler authenticationSuccessHandler; - private AuthenticationFailureHandler authenticationFailureHandler; - private LemonOidcUserService oidcUserService; - private LemonOAuth2UserService oauth2UserService; - private OAuth2AuthenticationSuccessHandler oauth2AuthenticationSuccessHandler; - private OAuth2AuthenticationFailureHandler oauth2AuthenticationFailureHandler; - private JpaJwtAuthenticationProvider jwtAuthenticationProvider; - private PasswordEncoder passwordEncoder; - - @Autowired - public void createLemonSecurityConfig(LemonProperties properties, UserDetailsService userDetailsService, - LemonAuthenticationSuccessHandler authenticationSuccessHandler, AuthenticationFailureHandler authenticationFailureHandler, - LemonOidcUserService oidcUserService, - LemonOAuth2UserService oauth2UserService, - OAuth2AuthenticationSuccessHandler oauth2AuthenticationSuccessHandler, - OAuth2AuthenticationFailureHandler oauth2AuthenticationFailureHandler, - JpaJwtAuthenticationProvider jwtAuthenticationProvider, - PasswordEncoder passwordEncoder - ) { - - this.properties = properties; - this.userDetailsService = userDetailsService; - this.authenticationSuccessHandler = authenticationSuccessHandler; - this.authenticationFailureHandler = authenticationFailureHandler; - this.oidcUserService = oidcUserService; - this.oauth2UserService = oauth2UserService; - this.oauth2AuthenticationSuccessHandler = oauth2AuthenticationSuccessHandler; - this.oauth2AuthenticationFailureHandler = oauth2AuthenticationFailureHandler; - this.jwtAuthenticationProvider = jwtAuthenticationProvider; - this.passwordEncoder = passwordEncoder; - - log.info("Created"); - } - - /** - * Security configuration, calling protected methods - */ - @Override - protected void configure(HttpSecurity http) throws Exception { - - sessionCreationPolicy(http); // set session creation policy - login(http); // authentication - logout(http); // logout related configuration - exceptionHandling(http); // exception handling - tokenAuthentication(http); // configure token authentication filter - csrf(http); // CSRF configuration - cors(http); // CORS configuration - oauth2Client(http); - authorizeRequests(http); // authorize requests - otherConfigurations(http); // override this to add more configurations - } - - - /** - * Configuring session creation policy - */ - protected void sessionCreationPolicy(HttpSecurity http) throws Exception { - - // No session - http.sessionManagement() - .sessionCreationPolicy(SessionCreationPolicy.STATELESS); - } - - - /** - * Configuring authentication. - */ - protected void login(HttpSecurity http) throws Exception { - - http - .formLogin() // form login - .loginPage(loginPage()) - - /****************************************** - * Setting a successUrl would redirect the user there. Instead, - * let's send 200 and the userDto along with an Authorization token. - *****************************************/ - .successHandler(authenticationSuccessHandler) - - /******************************************* - * Setting the failureUrl will redirect the user to - * that url if login fails. Instead, we need to send - * 401. So, let's set failureHandler instead. - *******************************************/ - .failureHandler(authenticationFailureHandler); - } - - - /** - * Override this to change login URL - * - * @return - */ - protected String loginPage() { - - return "/api/core/login"; - } - - /** - * Logout related configuration - */ - protected void logout(HttpSecurity http) throws Exception { - - http - .logout().disable(); // we are stateless; so /logout endpoint not needed - } - - - /** - * Configures exception-handling - */ - protected void exceptionHandling(HttpSecurity http) throws Exception { - - http - .exceptionHandling() - - /*********************************************** - * To prevent redirection to the login page - * when someone tries to access a restricted page - **********************************************/ - .authenticationEntryPoint(new Http403ForbiddenEntryPoint()); - } - - - /** - * Configuring token authentication filter - */ - protected void tokenAuthentication(HttpSecurity http) throws Exception { - - http.addFilterBefore(new LemonTokenAuthenticationFilter( - super.authenticationManager()), - UsernamePasswordAuthenticationFilter.class); - } - - - /** - * Disables CSRF. We are stateless. - */ - protected void csrf(HttpSecurity http) throws Exception { - - http - .csrf().disable(); - } - - - /** - * Configures CORS - */ - protected void cors(HttpSecurity http) throws Exception { - - http - .cors(); - } - - - private void oauth2Client(HttpSecurity http) throws Exception { - - http.oauth2Login() - .authorizationEndpoint() - .authorizationRequestRepository(new HttpCookieOAuth2AuthorizationRequestRepository(properties)).and() - .successHandler(oauth2AuthenticationSuccessHandler) - .failureHandler(oauth2AuthenticationFailureHandler) - .userInfoEndpoint() - .oidcUserService(oidcUserService) - .userService(oauth2UserService); - } - - - /** - * URL based authorization configuration. Override this if needed. - */ - protected void authorizeRequests(HttpSecurity http) throws Exception { - http.authorizeRequests() - .mvcMatchers("/**").permitAll(); - } - - - /** - * Override this to add more http configurations, - * such as more authentication methods. - * - * @param http - * @throws Exception - */ - protected void otherConfigurations(HttpSecurity http) throws Exception { - - } - - - /** - * Needed for configuring JwtAuthenticationProvider - */ - @Override - protected void configure(AuthenticationManagerBuilder auth) throws Exception { - - auth.userDetailsService(userDetailsService) - .passwordEncoder(passwordEncoder).and() - .authenticationProvider(jwtAuthenticationProvider); - } -} diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonJpaSecurityConfig.java b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonJpaSecurityConfig.java index fb616d5e..a2598b41 100644 --- a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonJpaSecurityConfig.java +++ b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonJpaSecurityConfig.java @@ -14,6 +14,7 @@ import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; import com.naturalprogrammer.spring.lemon.commons.LemonProperties; +import com.naturalprogrammer.spring.lemon.commonsweb.security.LemonCommonsWebSecurityConfig; import com.naturalprogrammer.spring.lemon.commonsweb.security.LemonTokenAuthenticationFilter; /** @@ -23,7 +24,7 @@ * * @author Sanjay Patel */ -public class LemonJpaSecurityConfig extends WebSecurityConfigurerAdapter { +public class LemonJpaSecurityConfig extends LemonCommonsWebSecurityConfig { private static final Log log = LogFactory.getLog(LemonJpaSecurityConfig.class); @@ -35,7 +36,6 @@ public class LemonJpaSecurityConfig extends WebSecurityConfigurerAdapter { private LemonOAuth2UserService oauth2UserService; private OAuth2AuthenticationSuccessHandler oauth2AuthenticationSuccessHandler; private OAuth2AuthenticationFailureHandler oauth2AuthenticationFailureHandler; - private JpaJwtAuthenticationProvider jwtAuthenticationProvider; private PasswordEncoder passwordEncoder; @Autowired @@ -45,9 +45,7 @@ public void createLemonSecurityConfig(LemonProperties properties, UserDetailsSer LemonOAuth2UserService oauth2UserService, OAuth2AuthenticationSuccessHandler oauth2AuthenticationSuccessHandler, OAuth2AuthenticationFailureHandler oauth2AuthenticationFailureHandler, - JpaJwtAuthenticationProvider jwtAuthenticationProvider, - PasswordEncoder passwordEncoder - ) { + PasswordEncoder passwordEncoder) { this.properties = properties; this.userDetailsService = userDetailsService; @@ -57,7 +55,6 @@ public void createLemonSecurityConfig(LemonProperties properties, UserDetailsSer this.oauth2UserService = oauth2UserService; this.oauth2AuthenticationSuccessHandler = oauth2AuthenticationSuccessHandler; this.oauth2AuthenticationFailureHandler = oauth2AuthenticationFailureHandler; - this.jwtAuthenticationProvider = jwtAuthenticationProvider; this.passwordEncoder = passwordEncoder; log.info("Created"); @@ -69,27 +66,10 @@ public void createLemonSecurityConfig(LemonProperties properties, UserDetailsSer @Override protected void configure(HttpSecurity http) throws Exception { - sessionCreationPolicy(http); // set session creation policy + super.configure(http); login(http); // authentication - logout(http); // logout related configuration exceptionHandling(http); // exception handling - tokenAuthentication(http); // configure token authentication filter - csrf(http); // CSRF configuration - cors(http); // CORS configuration oauth2Client(http); - authorizeRequests(http); // authorize requests - otherConfigurations(http); // override this to add more configurations - } - - - /** - * Configuring session creation policy - */ - protected void sessionCreationPolicy(HttpSecurity http) throws Exception { - - // No session - http.sessionManagement() - .sessionCreationPolicy(SessionCreationPolicy.STATELESS); } @@ -127,64 +107,8 @@ protected String loginPage() { return "/api/core/login"; } - /** - * Logout related configuration - */ - protected void logout(HttpSecurity http) throws Exception { - - http - .logout().disable(); // we are stateless; so /logout endpoint not needed - } - - - /** - * Configures exception-handling - */ - protected void exceptionHandling(HttpSecurity http) throws Exception { - - http - .exceptionHandling() - - /*********************************************** - * To prevent redirection to the login page - * when someone tries to access a restricted page - **********************************************/ - .authenticationEntryPoint(new Http403ForbiddenEntryPoint()); - } - - - /** - * Configuring token authentication filter - */ - protected void tokenAuthentication(HttpSecurity http) throws Exception { - - http.addFilterBefore(new LemonTokenAuthenticationFilter( - super.authenticationManager()), - UsernamePasswordAuthenticationFilter.class); - } - - - /** - * Disables CSRF. We are stateless. - */ - protected void csrf(HttpSecurity http) throws Exception { - - http - .csrf().disable(); - } - - - /** - * Configures CORS - */ - protected void cors(HttpSecurity http) throws Exception { - - http - .cors(); - } - - private void oauth2Client(HttpSecurity http) throws Exception { + protected void oauth2Client(HttpSecurity http) throws Exception { http.oauth2Login() .authorizationEndpoint() @@ -197,35 +121,14 @@ private void oauth2Client(HttpSecurity http) throws Exception { } - /** - * URL based authorization configuration. Override this if needed. - */ - protected void authorizeRequests(HttpSecurity http) throws Exception { - http.authorizeRequests() - .mvcMatchers("/**").permitAll(); - } - - - /** - * Override this to add more http configurations, - * such as more authentication methods. - * - * @param http - * @throws Exception - */ - protected void otherConfigurations(HttpSecurity http) throws Exception { - - } - - /** * Needed for configuring JwtAuthenticationProvider */ @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { + super.configure(auth); auth.userDetailsService(userDetailsService) - .passwordEncoder(passwordEncoder).and() - .authenticationProvider(jwtAuthenticationProvider); + .passwordEncoder(passwordEncoder); } } From 6f10a06334d60cfa9fec8f0e804b9f4ff1d5ecd0 Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Thu, 27 Sep 2018 16:51:14 +0530 Subject: [PATCH 050/116] spring-lemon-commons-web seems to be working --- .../LemonCommonsWebAutoConfiguration.java | 137 ++++++++++++++++++ .../security/JwtAuthenticationProvider.java | 3 - ...onfig.java => LemonWebSecurityConfig.java} | 6 +- .../lemon/commonsweb/util/LecwUtils.java | 10 ++ .../LemonCommonsAutoConfiguration.java | 13 ++ .../spring/lemon/LemonAutoConfiguration.java | 126 ++-------------- .../JpaJwtAuthenticationProvider.java | 6 - .../security/LemonJpaSecurityConfig.java | 9 +- 8 files changed, 178 insertions(+), 132 deletions(-) rename spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/security/{LemonCommonsWebSecurityConfig.java => LemonWebSecurityConfig.java} (90%) diff --git a/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/LemonCommonsWebAutoConfiguration.java b/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/LemonCommonsWebAutoConfiguration.java index 08e65c51..900c84d2 100644 --- a/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/LemonCommonsWebAutoConfiguration.java +++ b/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/LemonCommonsWebAutoConfiguration.java @@ -1,15 +1,39 @@ package com.naturalprogrammer.spring.lemon.commonsweb; +import java.util.List; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; import org.springframework.boot.autoconfigure.AutoConfigureBefore; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration; import org.springframework.boot.autoconfigure.security.servlet.SecurityFilterAutoConfiguration; +import org.springframework.boot.autoconfigure.web.ServerProperties; import org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration; import org.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConfiguration; +import org.springframework.boot.autoconfigure.web.servlet.error.ErrorViewResolver; +import org.springframework.boot.web.servlet.error.ErrorAttributes; +import org.springframework.boot.web.servlet.error.ErrorController; +import org.springframework.context.ApplicationContext; +import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.web.config.EnableSpringDataWebSupport; +import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; +import com.fasterxml.jackson.databind.ObjectMapper; import com.naturalprogrammer.spring.lemon.commons.LemonCommonsAutoConfiguration; +import com.naturalprogrammer.spring.lemon.commons.LemonProperties; +import com.naturalprogrammer.spring.lemon.commons.security.JwtService; +import com.naturalprogrammer.spring.lemon.commonsweb.exceptions.DefaultExceptionHandlerControllerAdvice; +import com.naturalprogrammer.spring.lemon.commonsweb.exceptions.LemonErrorAttributes; +import com.naturalprogrammer.spring.lemon.commonsweb.exceptions.LemonErrorController; +import com.naturalprogrammer.spring.lemon.commonsweb.security.JwtAuthenticationProvider; +import com.naturalprogrammer.spring.lemon.commonsweb.security.LemonCorsConfig; +import com.naturalprogrammer.spring.lemon.commonsweb.security.LemonWebSecurityConfig; +import com.naturalprogrammer.spring.lemon.commonsweb.util.LecwUtils; +import com.naturalprogrammer.spring.lemon.exceptions.ErrorResponseComposer; @Configuration @EnableSpringDataWebSupport @@ -22,5 +46,118 @@ LemonCommonsAutoConfiguration.class}) public class LemonCommonsWebAutoConfiguration { + /** + * For handling JSON vulnerability, + * JSON response bodies would be prefixed with + * this string. + */ + public final static String JSON_PREFIX = ")]}',\n"; + + private static final Log log = LogFactory.getLog(LemonCommonsWebAutoConfiguration.class); + + public LemonCommonsWebAutoConfiguration() { + log.info("Created"); + } + + /** + * Prefixes JSON responses for JSON vulnerability. Disabled by default. + * To enable, add this to your application properties: + * lemon.enabled.json-prefix: true + */ + @Bean + @ConditionalOnProperty(name="lemon.enabled.json-prefix") + public MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter( + ObjectMapper objectMapper) { + + log.info("Configuring JSON vulnerability prefix"); + + MappingJackson2HttpMessageConverter converter = + new MappingJackson2HttpMessageConverter(objectMapper); + converter.setJsonPrefix(JSON_PREFIX); + + return converter; + } + + /** + * Configures DefaultExceptionHandlerControllerAdvice if missing + */ + @Bean + @ConditionalOnMissingBean(DefaultExceptionHandlerControllerAdvice.class) + public + DefaultExceptionHandlerControllerAdvice defaultExceptionHandlerControllerAdvice(ErrorResponseComposer errorResponseComposer) { + + log.info("Configuring DefaultExceptionHandlerControllerAdvice"); + return new DefaultExceptionHandlerControllerAdvice(errorResponseComposer); + } + + /** + * Configures an Error Attributes if missing + */ + @Bean + @ConditionalOnMissingBean(ErrorAttributes.class) + public + ErrorAttributes errorAttributes(ErrorResponseComposer errorResponseComposer) { + + log.info("Configuring LemonErrorAttributes"); + return new LemonErrorAttributes(errorResponseComposer); + } + + /** + * Configures an Error Controller if missing + */ + @Bean + @ConditionalOnMissingBean(ErrorController.class) + public ErrorController errorController(ErrorAttributes errorAttributes, + ServerProperties serverProperties, + List errorViewResolvers) { + + log.info("Configuring LemonErrorController"); + return new LemonErrorController(errorAttributes, serverProperties, errorViewResolvers); + } + + /** + * Configures LemonCorsConfig if missing and lemon.cors.allowed-origins is provided + */ + @Bean + @ConditionalOnProperty(name="lemon.cors.allowed-origins") + @ConditionalOnMissingBean(LemonCorsConfig.class) + public LemonCorsConfig lemonCorsConfig(LemonProperties properties) { + + log.info("Configuring LemonCorsConfig"); + return new LemonCorsConfig(properties); + } + /** + * Configures JwtAuthenticationProvider if missing + */ + @Bean + @ConditionalOnMissingBean(JwtAuthenticationProvider.class) + public JwtAuthenticationProvider jwtAuthenticationProvider( + JwtService jwtService) { + + log.info("Configuring JwtAuthenticationProvider"); + return new JwtAuthenticationProvider(jwtService); + } + + /** + * Configures LemonSecurityConfig if missing + */ + @Bean + @ConditionalOnMissingBean(LemonWebSecurityConfig.class) + public LemonWebSecurityConfig lemonSecurityConfig() { + + log.info("Configuring LemonWebSecurityConfig"); + return new LemonWebSecurityConfig(); + } + + /** + * Configures LemonUtils + */ + @Bean + public LecwUtils lecwUtils(ApplicationContext applicationContext, + ObjectMapper objectMapper) { + + log.info("Configuring LecwUtils"); + return new LecwUtils(); + } } diff --git a/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/security/JwtAuthenticationProvider.java b/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/security/JwtAuthenticationProvider.java index b63b8f2a..16d7e903 100644 --- a/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/security/JwtAuthenticationProvider.java +++ b/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/security/JwtAuthenticationProvider.java @@ -1,13 +1,10 @@ package com.naturalprogrammer.spring.lemon.commonsweb.security; -import java.io.Serializable; - import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.security.authentication.AuthenticationCredentialsNotFoundException; import org.springframework.security.authentication.AuthenticationProvider; import org.springframework.security.core.Authentication; -import org.springframework.security.core.userdetails.UsernameNotFoundException; import com.naturalprogrammer.spring.lemon.commons.security.JwtAuthenticationToken; import com.naturalprogrammer.spring.lemon.commons.security.JwtService; diff --git a/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/security/LemonCommonsWebSecurityConfig.java b/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/security/LemonWebSecurityConfig.java similarity index 90% rename from spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/security/LemonCommonsWebSecurityConfig.java rename to spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/security/LemonWebSecurityConfig.java index 955e0f49..462362f8 100644 --- a/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/security/LemonCommonsWebSecurityConfig.java +++ b/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/security/LemonWebSecurityConfig.java @@ -17,14 +17,14 @@ * * @author Sanjay Patel */ -public class LemonCommonsWebSecurityConfig extends WebSecurityConfigurerAdapter { +public class LemonWebSecurityConfig extends WebSecurityConfigurerAdapter { - private static final Log log = LogFactory.getLog(LemonCommonsWebSecurityConfig.class); + private static final Log log = LogFactory.getLog(LemonWebSecurityConfig.class); private JwtAuthenticationProvider jwtAuthenticationProvider; @Autowired - public void createLemonCommonsWebSecurityConfig(JwtAuthenticationProvider jwtAuthenticationProvider) { + public void createLemonWebSecurityConfig(JwtAuthenticationProvider jwtAuthenticationProvider) { this.jwtAuthenticationProvider = jwtAuthenticationProvider; log.info("Created"); diff --git a/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/util/LecwUtils.java b/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/util/LecwUtils.java index 0293068b..a383a3bd 100644 --- a/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/util/LecwUtils.java +++ b/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/util/LecwUtils.java @@ -5,8 +5,18 @@ import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + public class LecwUtils { + private static final Log log = LogFactory.getLog(LecwUtils.class); + + public LecwUtils() { + + log.info("Created"); + } + /** * Fetches a cookie from the request */ diff --git a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/LemonCommonsAutoConfiguration.java b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/LemonCommonsAutoConfiguration.java index ed306971..8c4e39d2 100644 --- a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/LemonCommonsAutoConfiguration.java +++ b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/LemonCommonsAutoConfiguration.java @@ -5,6 +5,7 @@ import org.springframework.boot.autoconfigure.AutoConfigureBefore; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.boot.web.client.RestTemplateBuilder; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; @@ -23,6 +24,7 @@ import com.naturalprogrammer.spring.lemon.commons.security.JwtService; import com.naturalprogrammer.spring.lemon.commons.security.LemonPermissionEvaluator; import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; +import com.naturalprogrammer.spring.lemon.commons.validation.CaptchaValidator; import com.naturalprogrammer.spring.lemon.exceptions.LemonExceptionsAutoConfiguration; import com.nimbusds.jose.KeyLengthException; @@ -118,4 +120,15 @@ public MailSender smtpMailSender(JavaMailSender javaMailSender) { public LecUtils lecUtils(ApplicationContext applicationContext, ObjectMapper objectMapper) { return new LecUtils(applicationContext, objectMapper); } + + /** + * Configures CaptchaValidator if missing + */ + @Bean + @ConditionalOnMissingBean(CaptchaValidator.class) + public CaptchaValidator captchaValidator(LemonProperties properties, RestTemplateBuilder restTemplateBuilder) { + + log.info("Configuring LemonUserDetailsService"); + return new CaptchaValidator(properties, restTemplateBuilder); + } } diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/LemonAutoConfiguration.java b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/LemonAutoConfiguration.java index 6c79bc91..661d977c 100644 --- a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/LemonAutoConfiguration.java +++ b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/LemonAutoConfiguration.java @@ -1,30 +1,20 @@ package com.naturalprogrammer.spring.lemon; import java.io.Serializable; -import java.util.List; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.boot.autoconfigure.AutoConfigureBefore; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration; import org.springframework.boot.autoconfigure.security.servlet.SecurityFilterAutoConfiguration; -import org.springframework.boot.autoconfigure.web.ServerProperties; import org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration; import org.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConfiguration; -import org.springframework.boot.autoconfigure.web.servlet.error.ErrorViewResolver; -import org.springframework.boot.web.client.RestTemplateBuilder; -import org.springframework.boot.web.servlet.error.ErrorAttributes; -import org.springframework.boot.web.servlet.error.ErrorController; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.domain.AuditorAware; import org.springframework.data.jpa.repository.config.EnableJpaAuditing; -import org.springframework.data.web.config.EnableSpringDataWebSupport; -import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; -import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.web.authentication.AuthenticationFailureHandler; @@ -32,25 +22,20 @@ import org.springframework.transaction.annotation.EnableTransactionManagement; import com.fasterxml.jackson.databind.ObjectMapper; -import com.naturalprogrammer.spring.lemon.commons.LemonCommonsAutoConfiguration; import com.naturalprogrammer.spring.lemon.commons.LemonProperties; import com.naturalprogrammer.spring.lemon.commons.security.JwtService; -import com.naturalprogrammer.spring.lemon.commons.validation.CaptchaValidator; import com.naturalprogrammer.spring.lemon.commons.validation.RetypePasswordValidator; import com.naturalprogrammer.spring.lemon.commonsweb.LemonCommonsWebAutoConfiguration; -import com.naturalprogrammer.spring.lemon.commonsweb.exceptions.DefaultExceptionHandlerControllerAdvice; -import com.naturalprogrammer.spring.lemon.commonsweb.exceptions.LemonErrorAttributes; -import com.naturalprogrammer.spring.lemon.commonsweb.exceptions.LemonErrorController; -import com.naturalprogrammer.spring.lemon.commonsweb.security.LemonCorsConfig; +import com.naturalprogrammer.spring.lemon.commonsweb.security.JwtAuthenticationProvider; +import com.naturalprogrammer.spring.lemon.commonsweb.security.LemonWebSecurityConfig; import com.naturalprogrammer.spring.lemon.domain.AbstractUser; import com.naturalprogrammer.spring.lemon.domain.AbstractUserRepository; import com.naturalprogrammer.spring.lemon.domain.LemonAuditorAware; -import com.naturalprogrammer.spring.lemon.exceptions.ErrorResponseComposer; import com.naturalprogrammer.spring.lemon.security.JpaJwtAuthenticationProvider; import com.naturalprogrammer.spring.lemon.security.LemonAuthenticationSuccessHandler; +import com.naturalprogrammer.spring.lemon.security.LemonJpaSecurityConfig; import com.naturalprogrammer.spring.lemon.security.LemonOAuth2UserService; import com.naturalprogrammer.spring.lemon.security.LemonOidcUserService; -import com.naturalprogrammer.spring.lemon.security.LemonJpaSecurityConfig; import com.naturalprogrammer.spring.lemon.security.LemonUserDetailsService; import com.naturalprogrammer.spring.lemon.security.OAuth2AuthenticationFailureHandler; import com.naturalprogrammer.spring.lemon.security.OAuth2AuthenticationSuccessHandler; @@ -73,38 +58,12 @@ LemonCommonsWebAutoConfiguration.class}) public class LemonAutoConfiguration { - /** - * For handling JSON vulnerability, - * JSON response bodies would be prefixed with - * this string. - */ - public final static String JSON_PREFIX = ")]}',\n"; - private static final Log log = LogFactory.getLog(LemonAutoConfiguration.class); public LemonAutoConfiguration() { log.info("Created"); } - /** - * Prefixes JSON responses for JSON vulnerability. Disabled by default. - * To enable, add this to your application properties: - * lemon.enabled.json-prefix: true - */ - @Bean - @ConditionalOnProperty(name="lemon.enabled.json-prefix") - public MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter( - ObjectMapper objectMapper) { - - log.info("Configuring JSON vulnerability prefix"); - - MappingJackson2HttpMessageConverter converter = - new MappingJackson2HttpMessageConverter(objectMapper); - converter.setJsonPrefix(JSON_PREFIX); - - return converter; - } - /** * Configures an Auditor Aware if missing */ @@ -117,43 +76,6 @@ AuditorAware auditorAware(LemonService lemonService) { return new LemonAuditorAware(lemonService); } - /** - * Configures DefaultExceptionHandlerControllerAdvice if missing - */ - @Bean - @ConditionalOnMissingBean(DefaultExceptionHandlerControllerAdvice.class) - public - DefaultExceptionHandlerControllerAdvice defaultExceptionHandlerControllerAdvice(ErrorResponseComposer errorResponseComposer) { - - log.info("Configuring DefaultExceptionHandlerControllerAdvice"); - return new DefaultExceptionHandlerControllerAdvice(errorResponseComposer); - } - - /** - * Configures an Error Attributes if missing - */ - @Bean - @ConditionalOnMissingBean(ErrorAttributes.class) - public - ErrorAttributes errorAttributes(ErrorResponseComposer errorResponseComposer) { - - log.info("Configuring LemonErrorAttributes"); - return new LemonErrorAttributes(errorResponseComposer); - } - - /** - * Configures an Error Controller if missing - */ - @Bean - @ConditionalOnMissingBean(ErrorController.class) - public ErrorController errorController(ErrorAttributes errorAttributes, - ServerProperties serverProperties, - List errorViewResolvers) { - - log.info("Configuring LemonErrorController"); - return new LemonErrorController(errorAttributes, serverProperties, errorViewResolvers); - } - /** * Configures AuthenticationSuccessHandler if missing */ @@ -212,18 +134,6 @@ UserDetailsService userDetailService(AbstractUserRepository userRepositor return new LemonUserDetailsService(userRepository); } - /** - * Configures LemonCorsConfig if missing and lemon.cors.allowed-origins is provided - */ - @Bean - @ConditionalOnProperty(name="lemon.cors.allowed-origins") - @ConditionalOnMissingBean(LemonCorsConfig.class) - public LemonCorsConfig lemonCorsConfig(LemonProperties properties) { - - log.info("Configuring LemonCorsConfig"); - return new LemonCorsConfig(properties); - } - /** * Configures LemonOidcUserService if missing */ @@ -254,13 +164,13 @@ LemonOAuth2UserService lemonOAuth2UserService( * Configures JwtAuthenticationProvider if missing */ @Bean - @ConditionalOnMissingBean(JpaJwtAuthenticationProvider.class) + @ConditionalOnMissingBean(JwtAuthenticationProvider.class) public , ID extends Serializable> - JpaJwtAuthenticationProvider jwtAuthenticationProvider( + JwtAuthenticationProvider jwtAuthenticationProvider( JwtService jwtService, LemonUserDetailsService userDetailsService) { - log.info("Configuring JwtAuthenticationProvider"); + log.info("Configuring JpaJwtAuthenticationProvider"); return new JpaJwtAuthenticationProvider(jwtService, userDetailsService); } @@ -268,10 +178,10 @@ JpaJwtAuthenticationProvider jwtAuthenticationProvider( * Configures LemonSecurityConfig if missing */ @Bean - @ConditionalOnMissingBean(LemonJpaSecurityConfig.class) - public LemonJpaSecurityConfig lemonSecurityConfig() { + @ConditionalOnMissingBean(LemonWebSecurityConfig.class) + public LemonWebSecurityConfig lemonSecurityConfig() { - log.info("Configuring LemonSecurityConfig"); + log.info("Configuring LemonJpaSecurityConfig"); return new LemonJpaSecurityConfig(); } @@ -279,24 +189,13 @@ public LemonJpaSecurityConfig lemonSecurityConfig() { * Configures LemonUtils */ @Bean - public LemonUtils lemonUtil(ApplicationContext applicationContext, + public LemonUtils lemonUtils(ApplicationContext applicationContext, ObjectMapper objectMapper) { - log.info("Configuring LemonUtil"); + log.info("Configuring LemonUtils"); return new LemonUtils(); } - /** - * Configures CaptchaValidator if missing - */ - @Bean - @ConditionalOnMissingBean(CaptchaValidator.class) - public CaptchaValidator captchaValidator(LemonProperties properties, RestTemplateBuilder restTemplateBuilder) { - - log.info("Configuring LemonUserDetailsService"); - return new CaptchaValidator(properties, restTemplateBuilder); - } - /** * Configures RetypePasswordValidator if missing */ @@ -316,5 +215,6 @@ public UniqueEmailValidator uniqueEmailValidator(AbstractUserRepository us log.info("Configuring UniqueEmailValidator"); return new UniqueEmailValidator(userRepository); - } + } + } diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/JpaJwtAuthenticationProvider.java b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/JpaJwtAuthenticationProvider.java index 2396467e..02102ae3 100644 --- a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/JpaJwtAuthenticationProvider.java +++ b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/JpaJwtAuthenticationProvider.java @@ -4,18 +4,12 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import org.springframework.security.authentication.AuthenticationCredentialsNotFoundException; -import org.springframework.security.authentication.AuthenticationProvider; -import org.springframework.security.core.Authentication; import org.springframework.security.core.userdetails.UsernameNotFoundException; -import com.naturalprogrammer.spring.lemon.commons.security.JwtAuthenticationToken; import com.naturalprogrammer.spring.lemon.commons.security.JwtService; -import com.naturalprogrammer.spring.lemon.commons.security.LemonPrincipal; import com.naturalprogrammer.spring.lemon.commons.security.UserDto; import com.naturalprogrammer.spring.lemon.commonsweb.security.JwtAuthenticationProvider; import com.naturalprogrammer.spring.lemon.domain.AbstractUser; -import com.naturalprogrammer.spring.lemon.exceptions.util.LexUtils; import com.naturalprogrammer.spring.lemon.util.LemonUtils; import com.nimbusds.jwt.JWTClaimsSet; diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonJpaSecurityConfig.java b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonJpaSecurityConfig.java index a2598b41..14348845 100644 --- a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonJpaSecurityConfig.java +++ b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonJpaSecurityConfig.java @@ -5,17 +5,12 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.web.builders.HttpSecurity; -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.password.PasswordEncoder; import org.springframework.security.web.authentication.AuthenticationFailureHandler; -import org.springframework.security.web.authentication.Http403ForbiddenEntryPoint; -import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; import com.naturalprogrammer.spring.lemon.commons.LemonProperties; -import com.naturalprogrammer.spring.lemon.commonsweb.security.LemonCommonsWebSecurityConfig; -import com.naturalprogrammer.spring.lemon.commonsweb.security.LemonTokenAuthenticationFilter; +import com.naturalprogrammer.spring.lemon.commonsweb.security.LemonWebSecurityConfig; /** * Security configuration class. Extend it in the @@ -24,7 +19,7 @@ * * @author Sanjay Patel */ -public class LemonJpaSecurityConfig extends LemonCommonsWebSecurityConfig { +public class LemonJpaSecurityConfig extends LemonWebSecurityConfig { private static final Log log = LogFactory.getLog(LemonJpaSecurityConfig.class); From a21d8a0fc46c1b691a331dd7d50a69184be0a42b Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Thu, 27 Sep 2018 18:26:49 +0530 Subject: [PATCH 051/116] Moved currentUser() up --- .../spring/lemon/commonsweb/util/LecwUtils.java | 13 +++++++++++++ .../spring/lemon/LemonController.java | 4 ++-- .../spring/lemon/LemonService.java | 15 ++++++++------- .../spring/lemon/domain/LemonAuditorAware.java | 4 ++-- .../LemonAuthenticationSuccessHandler.java | 4 ++-- .../OAuth2AuthenticationSuccessHandler.java | 3 +-- .../spring/lemon/util/LemonUtils.java | 13 ++----------- 7 files changed, 30 insertions(+), 26 deletions(-) diff --git a/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/util/LecwUtils.java b/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/util/LecwUtils.java index a383a3bd..1801d6d4 100644 --- a/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/util/LecwUtils.java +++ b/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/util/LecwUtils.java @@ -1,5 +1,6 @@ package com.naturalprogrammer.spring.lemon.commonsweb.util; +import java.io.Serializable; import java.util.Optional; import javax.servlet.http.Cookie; @@ -7,6 +8,10 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.springframework.security.core.context.SecurityContextHolder; + +import com.naturalprogrammer.spring.lemon.commons.security.UserDto; +import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; public class LecwUtils { @@ -32,4 +37,12 @@ public static Optional fetchCookie(HttpServletRequest request, String na return Optional.empty(); } + /** + * Gets the current-user + */ + public static UserDto currentUser() { + + return LecUtils.currentUser(SecurityContextHolder.getContext()); + } + } diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/LemonController.java b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/LemonController.java index 4a02e45d..e9fe7c2b 100644 --- a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/LemonController.java +++ b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/LemonController.java @@ -29,9 +29,9 @@ import com.naturalprogrammer.spring.lemon.commons.security.UserDto; import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; import com.naturalprogrammer.spring.lemon.commons.util.UserUtils; +import com.naturalprogrammer.spring.lemon.commonsweb.util.LecwUtils; import com.naturalprogrammer.spring.lemon.domain.AbstractUser; import com.naturalprogrammer.spring.lemon.exceptions.util.LexUtils; -import com.naturalprogrammer.spring.lemon.util.LemonUtils; /** * The Lemon API. See the @@ -276,7 +276,7 @@ public Map fetchNewToken( */ protected UserDto userWithToken(HttpServletResponse response) { - UserDto currentUser = LemonUtils.currentUser(); + UserDto currentUser = LecwUtils.currentUser(); lemonService.addAuthHeader(response, currentUser.getUsername(), jwtExpirationMillis); return currentUser; } diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/LemonService.java b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/LemonService.java index dc501198..6eae70aa 100644 --- a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/LemonService.java +++ b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/LemonService.java @@ -37,6 +37,7 @@ import com.naturalprogrammer.spring.lemon.commons.security.UserEditPermission; import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; import com.naturalprogrammer.spring.lemon.commons.util.UserUtils; +import com.naturalprogrammer.spring.lemon.commonsweb.util.LecwUtils; import com.naturalprogrammer.spring.lemon.domain.AbstractUser; import com.naturalprogrammer.spring.lemon.domain.AbstractUserRepository; import com.naturalprogrammer.spring.lemon.exceptions.util.LexUtils; @@ -176,14 +177,14 @@ public Map getContext(Optional expirationMillis, HttpServl sharedProperties.put("reCaptchaSiteKey", properties.getRecaptcha().getSitekey()); sharedProperties.put("shared", properties.getShared()); - UserDto currentUser = LemonUtils.currentUser(); + UserDto currentUser = LecwUtils.currentUser(); if (currentUser != null) addAuthHeader(response, currentUser.getUsername(), expirationMillis.orElse(properties.getJwt().getExpirationMillis())); return LecUtils.mapOf( "context", sharedProperties, - "user", LemonUtils.currentUser()); + "user", LecwUtils.currentUser()); } @@ -457,7 +458,7 @@ public UserDto updateUser(U user, @Valid U updatedUser) { LemonUtils.ensureCorrectVersion(user, updatedUser); // delegates to updateUserFields - updateUserFields(user, updatedUser, LemonUtils.currentUser()); + updateUserFields(user, updatedUser, LecwUtils.currentUser()); userRepository.save(user); log.debug("Updated user: " + user); @@ -478,7 +479,7 @@ public String changePassword(U user, @Valid ChangePasswordForm changePasswordFor log.debug("Changing password for user: " + user); // Get the old password of the logged in user (logged in user may be an ADMIN) - UserDto currentUser = LemonUtils.currentUser(); + UserDto currentUser = LecwUtils.currentUser(); U loggedIn = userRepository.findById(toId(currentUser.getId())).get(); String oldPassword = loggedIn.getPassword(); @@ -622,7 +623,7 @@ public void changeEmail(ID userId, @Valid @NotBlank String changeEmailCode) { log.debug("Changing email of current user ..."); // fetch the current-user - UserDto currentUser = LemonUtils.currentUser(); + UserDto currentUser = LecwUtils.currentUser(); LexUtils.validate(userId.equals(toId(currentUser.getId())), "com.naturalprogrammer.spring.wrong.login").go(); @@ -709,7 +710,7 @@ public boolean getOAuth2AccountVerified(String registrationId, Map expirationMillis, Optional optionalUsername) { - UserDto currentUser = LemonUtils.currentUser(); + UserDto currentUser = LecwUtils.currentUser(); String username = optionalUsername.orElse(currentUser.getUsername()); LecUtils.ensureAuthority(currentUser.getUsername().equals(username) || @@ -738,7 +739,7 @@ protected void hideConfidentialFields(U user) { user.setPassword(null); // JsonIgnore didn't work - if (!user.hasPermission(LemonUtils.currentUser(), UserUtils.Permission.EDIT)) + if (!user.hasPermission(LecwUtils.currentUser(), UserUtils.Permission.EDIT)) user.setEmail(null); log.debug("Hid confidential fields for user: " + user); diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/domain/LemonAuditorAware.java b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/domain/LemonAuditorAware.java index 2b0f7d4e..6da5e391 100644 --- a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/domain/LemonAuditorAware.java +++ b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/domain/LemonAuditorAware.java @@ -9,7 +9,7 @@ import com.naturalprogrammer.spring.lemon.LemonService; import com.naturalprogrammer.spring.lemon.commons.security.UserDto; -import com.naturalprogrammer.spring.lemon.util.LemonUtils; +import com.naturalprogrammer.spring.lemon.commonsweb.util.LecwUtils; /** * Needed for auto-filling of the @@ -35,7 +35,7 @@ public LemonAuditorAware(LemonService lemonService) { @Override public Optional getCurrentAuditor() { - UserDto currentUser = LemonUtils.currentUser(); + UserDto currentUser = LecwUtils.currentUser(); if (currentUser == null) return Optional.empty(); diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonAuthenticationSuccessHandler.java b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonAuthenticationSuccessHandler.java index 7940acd4..fce739a8 100644 --- a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonAuthenticationSuccessHandler.java +++ b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonAuthenticationSuccessHandler.java @@ -16,7 +16,7 @@ import com.naturalprogrammer.spring.lemon.LemonService; import com.naturalprogrammer.spring.lemon.commons.LemonProperties; import com.naturalprogrammer.spring.lemon.commons.security.UserDto; -import com.naturalprogrammer.spring.lemon.util.LemonUtils; +import com.naturalprogrammer.spring.lemon.commonsweb.util.LecwUtils; /** * Authentication success handler for sending the response @@ -59,7 +59,7 @@ public void onAuthenticationSuccess(HttpServletRequest request, defaultExpirationMillis : Long.valueOf(expirationMillisStr); // get the current-user - UserDto currentUser = LemonUtils.currentUser(); + UserDto currentUser = LecwUtils.currentUser(); lemonService.addAuthHeader(response, currentUser.getUsername(), expirationMillis); diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/OAuth2AuthenticationSuccessHandler.java b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/OAuth2AuthenticationSuccessHandler.java index ee67f148..448f1270 100644 --- a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/OAuth2AuthenticationSuccessHandler.java +++ b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/OAuth2AuthenticationSuccessHandler.java @@ -14,7 +14,6 @@ import com.naturalprogrammer.spring.lemon.commons.security.JwtService; import com.naturalprogrammer.spring.lemon.commons.security.UserDto; import com.naturalprogrammer.spring.lemon.commonsweb.util.LecwUtils; -import com.naturalprogrammer.spring.lemon.util.LemonUtils; /** * Authentication success handler for redirecting the @@ -42,7 +41,7 @@ public OAuth2AuthenticationSuccessHandler(LemonProperties properties, JwtService protected String determineTargetUrl(HttpServletRequest request, HttpServletResponse response) { - UserDto currentUser = LemonUtils.currentUser(); + UserDto currentUser = LecwUtils.currentUser(); String shortLivedAuthToken = jwtService.createToken( JwtService.AUTH_AUDIENCE, diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/util/LemonUtils.java b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/util/LemonUtils.java index 20b0b747..9c273dd2 100644 --- a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/util/LemonUtils.java +++ b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/util/LemonUtils.java @@ -12,7 +12,6 @@ import com.naturalprogrammer.spring.lemon.commons.security.JwtService; import com.naturalprogrammer.spring.lemon.commons.security.LemonPrincipal; -import com.naturalprogrammer.spring.lemon.commons.security.UserDto; import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; import com.naturalprogrammer.spring.lemon.domain.AbstractUser; import com.naturalprogrammer.spring.lemon.domain.VersionedEntity; @@ -34,15 +33,6 @@ public LemonUtils() { } - /** - * Gets the current-user - */ - public static UserDto currentUser() { - - return LecUtils.currentUser(SecurityContextHolder.getContext()); - } - - /** * Signs a user in * @@ -75,6 +65,7 @@ void ensureCorrectVersion(VersionedEntity original, VersionedEntity throw new VersionException(original.getClass().getSimpleName(), original.getId().toString()); } + /** * A convenient method for running code * after successful database commit. @@ -92,7 +83,7 @@ public void afterCommit() { } }); } - + /** * Throws BadCredentialsException if From 0451cf4191656c9d6e893533994b363a9436b876 Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Sat, 29 Sep 2018 07:33:07 +0530 Subject: [PATCH 052/116] Added a couple of modules --- .../spring/lemondemo/services/MyService.java | 4 +- pom.xml | 2 + spring-lemon-commons-jpa/pom.xml | 39 ++++++++++++++++++ .../spring/lemon/commonsjpa/LecjUtils.java | 26 ++++++++++++ .../LemonCommonsJpaAutoConfiguration.java | 16 ++++++++ .../src/main/resources/META-INF/orm.xml | 18 +++++++++ .../main/resources/META-INF/spring.factories | 2 + spring-lemon-commons-mongo/pom.xml | 40 +++++++++++++++++++ .../lemon/commonsmongo}/AbstractDocument.java | 2 +- .../spring/lemon/commonsmongo/LecmUtils.java | 23 +++++++++++ .../LemonCommonsMongoAutoConfiguration.java | 17 ++++++++ .../main/resources/META-INF/spring.factories | 2 + ...LemonCommonsReactiveAutoConfiguration.java | 3 ++ .../handlers/VersionExceptionHandler.java | 2 +- spring-lemon-jpa/pom.xml | 7 +--- .../spring/lemon/LemonAutoConfiguration.java | 13 +----- .../spring/lemon/LemonService.java | 13 +++--- .../spring/lemon/util/LemonUtils.java | 21 ---------- spring-lemon-reactive/pom.xml | 7 +--- .../LemonReactiveAutoConfiguration.java | 13 +----- .../lemonreactive/LemonReactiveService.java | 3 +- .../domain/AbstractMongoUser.java | 1 + .../spring/lemonreactive/util/LerUtils.java | 16 -------- 23 files changed, 208 insertions(+), 82 deletions(-) create mode 100644 spring-lemon-commons-jpa/pom.xml create mode 100644 spring-lemon-commons-jpa/src/main/java/com/naturalprogrammer/spring/lemon/commonsjpa/LecjUtils.java create mode 100644 spring-lemon-commons-jpa/src/main/java/com/naturalprogrammer/spring/lemon/commonsjpa/LemonCommonsJpaAutoConfiguration.java create mode 100644 spring-lemon-commons-jpa/src/main/resources/META-INF/orm.xml create mode 100644 spring-lemon-commons-jpa/src/main/resources/META-INF/spring.factories create mode 100644 spring-lemon-commons-mongo/pom.xml rename {spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/domain => spring-lemon-commons-mongo/src/main/java/com/naturalprogrammer/spring/lemon/commonsmongo}/AbstractDocument.java (91%) create mode 100644 spring-lemon-commons-mongo/src/main/java/com/naturalprogrammer/spring/lemon/commonsmongo/LecmUtils.java create mode 100644 spring-lemon-commons-mongo/src/main/java/com/naturalprogrammer/spring/lemon/commonsmongo/LemonCommonsMongoAutoConfiguration.java create mode 100644 spring-lemon-commons-mongo/src/main/resources/META-INF/spring.factories rename {spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive => spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive}/exceptions/handlers/VersionExceptionHandler.java (86%) diff --git a/lemon-demo-jpa/src/main/java/com/naturalprogrammer/spring/lemondemo/services/MyService.java b/lemon-demo-jpa/src/main/java/com/naturalprogrammer/spring/lemondemo/services/MyService.java index b521a588..2d14457b 100644 --- a/lemon-demo-jpa/src/main/java/com/naturalprogrammer/spring/lemondemo/services/MyService.java +++ b/lemon-demo-jpa/src/main/java/com/naturalprogrammer/spring/lemondemo/services/MyService.java @@ -7,7 +7,7 @@ import com.naturalprogrammer.spring.lemon.LemonService; import com.naturalprogrammer.spring.lemon.commons.security.UserDto; -import com.naturalprogrammer.spring.lemon.util.LemonUtils; +import com.naturalprogrammer.spring.lemon.commonsjpa.LecjUtils; import com.naturalprogrammer.spring.lemondemo.entities.User; @Service @@ -27,7 +27,7 @@ protected void updateUserFields(User user, User updatedUser, UserDto currentUser user.setName(updatedUser.getName()); - LemonUtils.afterCommit(() -> { + LecjUtils.afterCommit(() -> { if (currentUser.getId().equals(user.getId().toString())) currentUser.setTag(user.toTag()); }); diff --git a/pom.xml b/pom.xml index 63ec868d..e16ecf2b 100644 --- a/pom.xml +++ b/pom.xml @@ -24,6 +24,8 @@ spring-lemon-commons spring-lemon-commons-web spring-lemon-commons-reactive + spring-lemon-commons-jpa + spring-lemon-commons-mongo spring-lemon-jpa spring-lemon-reactive lemon-demo-jpa diff --git a/spring-lemon-commons-jpa/pom.xml b/spring-lemon-commons-jpa/pom.xml new file mode 100644 index 00000000..26e35cc2 --- /dev/null +++ b/spring-lemon-commons-jpa/pom.xml @@ -0,0 +1,39 @@ + + + 4.0.0 + + com.naturalprogrammer.spring-lemon + spring-lemon-commons-jpa + jar + + spring-lemon-commons-jpa + Spring Lemon Commons JPA + + + com.naturalprogrammer + spring-lemon + 1.0.0.M7 + + + + + + com.naturalprogrammer.spring-lemon + spring-lemon-commons-web + ${project.version} + + + + org.springframework.boot + spring-boot-starter-data-jpa + + + + javax.xml.bind + jaxb-api + + + + + diff --git a/spring-lemon-commons-jpa/src/main/java/com/naturalprogrammer/spring/lemon/commonsjpa/LecjUtils.java b/spring-lemon-commons-jpa/src/main/java/com/naturalprogrammer/spring/lemon/commonsjpa/LecjUtils.java new file mode 100644 index 00000000..e2d804ee --- /dev/null +++ b/spring-lemon-commons-jpa/src/main/java/com/naturalprogrammer/spring/lemon/commonsjpa/LecjUtils.java @@ -0,0 +1,26 @@ +package com.naturalprogrammer.spring.lemon.commonsjpa; + +import org.springframework.transaction.support.TransactionSynchronizationAdapter; +import org.springframework.transaction.support.TransactionSynchronizationManager; + +public class LecjUtils { + + /** + * A convenient method for running code + * after successful database commit. + * + * @param runnable + */ + public static void afterCommit(Runnable runnable) { + + TransactionSynchronizationManager.registerSynchronization( + new TransactionSynchronizationAdapter() { + @Override + public void afterCommit() { + + runnable.run(); + } + }); + } + +} diff --git a/spring-lemon-commons-jpa/src/main/java/com/naturalprogrammer/spring/lemon/commonsjpa/LemonCommonsJpaAutoConfiguration.java b/spring-lemon-commons-jpa/src/main/java/com/naturalprogrammer/spring/lemon/commonsjpa/LemonCommonsJpaAutoConfiguration.java new file mode 100644 index 00000000..7b51d479 --- /dev/null +++ b/spring-lemon-commons-jpa/src/main/java/com/naturalprogrammer/spring/lemon/commonsjpa/LemonCommonsJpaAutoConfiguration.java @@ -0,0 +1,16 @@ +package com.naturalprogrammer.spring.lemon.commonsjpa; + +import org.springframework.boot.autoconfigure.AutoConfigureBefore; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.jpa.repository.config.EnableJpaAuditing; +import org.springframework.transaction.annotation.EnableTransactionManagement; + +import com.naturalprogrammer.spring.lemon.commonsweb.LemonCommonsWebAutoConfiguration; + +@Configuration +@EnableTransactionManagement +@EnableJpaAuditing +@AutoConfigureBefore({LemonCommonsWebAutoConfiguration.class}) +public class LemonCommonsJpaAutoConfiguration { + +} diff --git a/spring-lemon-commons-jpa/src/main/resources/META-INF/orm.xml b/spring-lemon-commons-jpa/src/main/resources/META-INF/orm.xml new file mode 100644 index 00000000..a5a5f13d --- /dev/null +++ b/spring-lemon-commons-jpa/src/main/resources/META-INF/orm.xml @@ -0,0 +1,18 @@ + + + + JPA + + + + + + + + + + diff --git a/spring-lemon-commons-jpa/src/main/resources/META-INF/spring.factories b/spring-lemon-commons-jpa/src/main/resources/META-INF/spring.factories new file mode 100644 index 00000000..c4284f64 --- /dev/null +++ b/spring-lemon-commons-jpa/src/main/resources/META-INF/spring.factories @@ -0,0 +1,2 @@ +org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ +com.naturalprogrammer.spring.lemon.commonsjpa.LemonCommonsJpaAutoConfiguration \ No newline at end of file diff --git a/spring-lemon-commons-mongo/pom.xml b/spring-lemon-commons-mongo/pom.xml new file mode 100644 index 00000000..01b9f1aa --- /dev/null +++ b/spring-lemon-commons-mongo/pom.xml @@ -0,0 +1,40 @@ + + + 4.0.0 + + com.naturalprogrammer.spring-lemon + spring-lemon-commons-mongo + jar + + spring-lemon-commons-mongo + Spring Lemon Commons MongoDB + + + com.naturalprogrammer + spring-lemon + 1.0.0.M7 + + + + + + com.naturalprogrammer.spring-lemon + spring-lemon-commons-reactive + ${project.version} + + + + org.springframework.boot + spring-boot-starter-data-mongodb-reactive + + + + io.projectreactor + reactor-test + test + + + + + diff --git a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/domain/AbstractDocument.java b/spring-lemon-commons-mongo/src/main/java/com/naturalprogrammer/spring/lemon/commonsmongo/AbstractDocument.java similarity index 91% rename from spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/domain/AbstractDocument.java rename to spring-lemon-commons-mongo/src/main/java/com/naturalprogrammer/spring/lemon/commonsmongo/AbstractDocument.java index 11bf73b5..5e4cc5a6 100644 --- a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/domain/AbstractDocument.java +++ b/spring-lemon-commons-mongo/src/main/java/com/naturalprogrammer/spring/lemon/commonsmongo/AbstractDocument.java @@ -1,4 +1,4 @@ -package com.naturalprogrammer.spring.lemonreactive.domain; +package com.naturalprogrammer.spring.lemon.commonsmongo; import java.io.Serializable; import java.time.Instant; diff --git a/spring-lemon-commons-mongo/src/main/java/com/naturalprogrammer/spring/lemon/commonsmongo/LecmUtils.java b/spring-lemon-commons-mongo/src/main/java/com/naturalprogrammer/spring/lemon/commonsmongo/LecmUtils.java new file mode 100644 index 00000000..33507b86 --- /dev/null +++ b/spring-lemon-commons-mongo/src/main/java/com/naturalprogrammer/spring/lemon/commonsmongo/LecmUtils.java @@ -0,0 +1,23 @@ +package com.naturalprogrammer.spring.lemon.commonsmongo; + +import java.io.Serializable; + +import com.naturalprogrammer.spring.lemon.exceptions.VersionException; + +public class LecmUtils { + + /** + * Throws a VersionException if the versions of the + * given entities aren't same. + * + * @param original + * @param updated + */ + public static + void ensureCorrectVersion(AbstractDocument original, AbstractDocument updated) { + + if (original.getVersion() != updated.getVersion()) + throw new VersionException(original.getClass().getSimpleName(), original.getId().toString()); + } + +} diff --git a/spring-lemon-commons-mongo/src/main/java/com/naturalprogrammer/spring/lemon/commonsmongo/LemonCommonsMongoAutoConfiguration.java b/spring-lemon-commons-mongo/src/main/java/com/naturalprogrammer/spring/lemon/commonsmongo/LemonCommonsMongoAutoConfiguration.java new file mode 100644 index 00000000..8d57c1eb --- /dev/null +++ b/spring-lemon-commons-mongo/src/main/java/com/naturalprogrammer/spring/lemon/commonsmongo/LemonCommonsMongoAutoConfiguration.java @@ -0,0 +1,17 @@ +package com.naturalprogrammer.spring.lemon.commonsmongo; + +import org.springframework.boot.autoconfigure.AutoConfigureBefore; +import org.springframework.boot.autoconfigure.mongo.MongoReactiveAutoConfiguration; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.mongodb.config.EnableMongoAuditing; + +import com.naturalprogrammer.spring.lemon.commonsreactive.LemonCommonsReactiveAutoConfiguration; + +@Configuration +@EnableMongoAuditing +@AutoConfigureBefore({ + MongoReactiveAutoConfiguration.class, + LemonCommonsReactiveAutoConfiguration.class}) +public class LemonCommonsMongoAutoConfiguration { + +} diff --git a/spring-lemon-commons-mongo/src/main/resources/META-INF/spring.factories b/spring-lemon-commons-mongo/src/main/resources/META-INF/spring.factories new file mode 100644 index 00000000..a567becb --- /dev/null +++ b/spring-lemon-commons-mongo/src/main/resources/META-INF/spring.factories @@ -0,0 +1,2 @@ +org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ +com.naturalprogrammer.spring.lemon.commonsmongo.LemonCommonsMongoAutoConfiguration \ No newline at end of file diff --git a/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/LemonCommonsReactiveAutoConfiguration.java b/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/LemonCommonsReactiveAutoConfiguration.java index d909068a..80405991 100644 --- a/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/LemonCommonsReactiveAutoConfiguration.java +++ b/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/LemonCommonsReactiveAutoConfiguration.java @@ -11,6 +11,7 @@ import org.springframework.boot.autoconfigure.web.reactive.error.ErrorWebFluxAutoConfiguration; import org.springframework.boot.web.reactive.error.ErrorAttributes; import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.security.access.PermissionEvaluator; import org.springframework.security.access.expression.AbstractSecurityExpressionHandler; @@ -24,6 +25,7 @@ import com.naturalprogrammer.spring.lemon.commons.LemonProperties; import com.naturalprogrammer.spring.lemon.commons.security.JwtService; import com.naturalprogrammer.spring.lemon.commonsreactive.exceptions.LemonReactiveErrorAttributes; +import com.naturalprogrammer.spring.lemon.commonsreactive.exceptions.handlers.VersionExceptionHandler; import com.naturalprogrammer.spring.lemon.commonsreactive.security.LemonCommonsReactiveSecurityConfig; import com.naturalprogrammer.spring.lemon.commonsreactive.security.LemonReactiveCorsConfig; import com.naturalprogrammer.spring.lemon.commonsreactive.util.LecrUtils; @@ -37,6 +39,7 @@ ErrorWebFluxAutoConfiguration.class, ReactiveSecurityAutoConfiguration.class, LemonCommonsAutoConfiguration.class}) +@ComponentScan(basePackageClasses=VersionExceptionHandler.class) public class LemonCommonsReactiveAutoConfiguration { private static final Log log = LogFactory.getLog(LemonCommonsReactiveAutoConfiguration.class); diff --git a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/exceptions/handlers/VersionExceptionHandler.java b/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/exceptions/handlers/VersionExceptionHandler.java similarity index 86% rename from spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/exceptions/handlers/VersionExceptionHandler.java rename to spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/exceptions/handlers/VersionExceptionHandler.java index 27cd4359..1db80d48 100644 --- a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/exceptions/handlers/VersionExceptionHandler.java +++ b/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/exceptions/handlers/VersionExceptionHandler.java @@ -1,4 +1,4 @@ -package com.naturalprogrammer.spring.lemonreactive.exceptions.handlers; +package com.naturalprogrammer.spring.lemon.commonsreactive.exceptions.handlers; import org.springframework.core.Ordered; import org.springframework.core.annotation.Order; diff --git a/spring-lemon-jpa/pom.xml b/spring-lemon-jpa/pom.xml index 40fcfa08..7657b0e9 100644 --- a/spring-lemon-jpa/pom.xml +++ b/spring-lemon-jpa/pom.xml @@ -20,15 +20,10 @@ com.naturalprogrammer.spring-lemon - spring-lemon-commons-web + spring-lemon-commons-jpa ${project.version} - - org.springframework.boot - spring-boot-starter-data-jpa - - javax.xml.bind jaxb-api diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/LemonAutoConfiguration.java b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/LemonAutoConfiguration.java index 661d977c..ef5a3c3f 100644 --- a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/LemonAutoConfiguration.java +++ b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/LemonAutoConfiguration.java @@ -6,10 +6,6 @@ import org.apache.commons.logging.LogFactory; import org.springframework.boot.autoconfigure.AutoConfigureBefore; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration; -import org.springframework.boot.autoconfigure.security.servlet.SecurityFilterAutoConfiguration; -import org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration; -import org.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConfiguration; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -25,7 +21,7 @@ import com.naturalprogrammer.spring.lemon.commons.LemonProperties; import com.naturalprogrammer.spring.lemon.commons.security.JwtService; import com.naturalprogrammer.spring.lemon.commons.validation.RetypePasswordValidator; -import com.naturalprogrammer.spring.lemon.commonsweb.LemonCommonsWebAutoConfiguration; +import com.naturalprogrammer.spring.lemon.commonsjpa.LemonCommonsJpaAutoConfiguration; import com.naturalprogrammer.spring.lemon.commonsweb.security.JwtAuthenticationProvider; import com.naturalprogrammer.spring.lemon.commonsweb.security.LemonWebSecurityConfig; import com.naturalprogrammer.spring.lemon.domain.AbstractUser; @@ -50,12 +46,7 @@ @Configuration @EnableTransactionManagement @EnableJpaAuditing -@AutoConfigureBefore({ - WebMvcAutoConfiguration.class, - ErrorMvcAutoConfiguration.class, - SecurityAutoConfiguration.class, - SecurityFilterAutoConfiguration.class, - LemonCommonsWebAutoConfiguration.class}) +@AutoConfigureBefore({LemonCommonsJpaAutoConfiguration.class}) public class LemonAutoConfiguration { private static final Log log = LogFactory.getLog(LemonAutoConfiguration.class); diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/LemonService.java b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/LemonService.java index 6eae70aa..487659ff 100644 --- a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/LemonService.java +++ b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/LemonService.java @@ -37,6 +37,7 @@ import com.naturalprogrammer.spring.lemon.commons.security.UserEditPermission; import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; import com.naturalprogrammer.spring.lemon.commons.util.UserUtils; +import com.naturalprogrammer.spring.lemon.commonsjpa.LecjUtils; import com.naturalprogrammer.spring.lemon.commonsweb.util.LecwUtils; import com.naturalprogrammer.spring.lemon.domain.AbstractUser; import com.naturalprogrammer.spring.lemon.domain.AbstractUserRepository; @@ -201,7 +202,7 @@ public void signup(@Valid U user) { userRepository.save(user); // if successfully committed - LemonUtils.afterCommit(() -> { + LecjUtils.afterCommit(() -> { LemonUtils.login(user); // log the user in log.debug("Signed up user: " + user); @@ -229,7 +230,7 @@ protected void makeUnverified(U user) { user.getRoles().add(UserUtils.Role.UNVERIFIED); user.setCredentialsUpdatedMillis(System.currentTimeMillis()); - LemonUtils.afterCommit(() -> sendVerificationMail(user)); // send a verification mail to the user + LecjUtils.afterCommit(() -> sendVerificationMail(user)); // send a verification mail to the user } @@ -346,7 +347,7 @@ public void verifyUser(ID userId, String verificationCode) { userRepository.save(user); // after successful commit, - LemonUtils.afterCommit(() -> { + LecjUtils.afterCommit(() -> { // Re-login the user, so that the UNVERIFIED role is removed LemonUtils.login(user); @@ -434,7 +435,7 @@ public void resetPassword(@Valid ResetPasswordForm form) { userRepository.save(user); // after successful commit, - LemonUtils.afterCommit(() -> { + LecjUtils.afterCommit(() -> { // Login the user LemonUtils.login(user); @@ -561,7 +562,7 @@ public void requestEmailChange(U user, @Valid U updatedUser) { userRepository.save(user); // after successful commit, mails a link to the user - LemonUtils.afterCommit(() -> mailChangeEmailLink(user)); + LecjUtils.afterCommit(() -> mailChangeEmailLink(user)); log.debug("Requested email change: " + user); } @@ -660,7 +661,7 @@ public void changeEmail(ID userId, @Valid @NotBlank String changeEmailCode) { userRepository.save(user); // after successful commit, - LemonUtils.afterCommit(() -> { + LecjUtils.afterCommit(() -> { // Login the user LemonUtils.login(user); diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/util/LemonUtils.java b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/util/LemonUtils.java index 9c273dd2..c2cfc9c7 100644 --- a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/util/LemonUtils.java +++ b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/util/LemonUtils.java @@ -7,8 +7,6 @@ import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContextHolder; -import org.springframework.transaction.support.TransactionSynchronizationAdapter; -import org.springframework.transaction.support.TransactionSynchronizationManager; import com.naturalprogrammer.spring.lemon.commons.security.JwtService; import com.naturalprogrammer.spring.lemon.commons.security.LemonPrincipal; @@ -66,25 +64,6 @@ void ensureCorrectVersion(VersionedEntity original, VersionedEntity } - /** - * A convenient method for running code - * after successful database commit. - * - * @param runnable - */ - public static void afterCommit(Runnable runnable) { - - TransactionSynchronizationManager.registerSynchronization( - new TransactionSynchronizationAdapter() { - @Override - public void afterCommit() { - - runnable.run(); - } - }); - } - - /** * Throws BadCredentialsException if * user's credentials were updated after the JWT was issued diff --git a/spring-lemon-reactive/pom.xml b/spring-lemon-reactive/pom.xml index e264c649..f3eeb2ae 100644 --- a/spring-lemon-reactive/pom.xml +++ b/spring-lemon-reactive/pom.xml @@ -20,15 +20,10 @@ com.naturalprogrammer.spring-lemon - spring-lemon-commons-reactive + spring-lemon-commons-mongo ${project.version} - - org.springframework.boot - spring-boot-starter-data-mongodb-reactive - - io.projectreactor reactor-test diff --git a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveAutoConfiguration.java b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveAutoConfiguration.java index 3cfea678..7fc2ca9b 100644 --- a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveAutoConfiguration.java +++ b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveAutoConfiguration.java @@ -6,33 +6,24 @@ import org.apache.commons.logging.LogFactory; import org.springframework.boot.autoconfigure.AutoConfigureBefore; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.mongo.MongoReactiveAutoConfiguration; import org.springframework.boot.autoconfigure.security.reactive.ReactiveUserDetailsServiceAutoConfiguration; import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; -import org.springframework.data.mongodb.config.EnableMongoAuditing; -import org.springframework.security.config.annotation.method.configuration.EnableReactiveMethodSecurity; import org.springframework.security.core.userdetails.UserDetailsService; import com.naturalprogrammer.spring.lemon.commons.security.JwtService; -import com.naturalprogrammer.spring.lemon.commonsreactive.LemonCommonsReactiveAutoConfiguration; +import com.naturalprogrammer.spring.lemon.commonsmongo.LemonCommonsMongoAutoConfiguration; import com.naturalprogrammer.spring.lemon.exceptions.util.LexUtils; import com.naturalprogrammer.spring.lemonreactive.domain.AbstractMongoUser; import com.naturalprogrammer.spring.lemonreactive.domain.AbstractMongoUserRepository; -import com.naturalprogrammer.spring.lemonreactive.exceptions.handlers.VersionExceptionHandler; import com.naturalprogrammer.spring.lemonreactive.security.LemonReactiveSecurityConfig; import com.naturalprogrammer.spring.lemonreactive.security.LemonReactiveUserDetailsService; import com.naturalprogrammer.spring.lemonreactive.util.LerUtils; @Configuration -@EnableMongoAuditing -@EnableReactiveMethodSecurity @AutoConfigureBefore({ - MongoReactiveAutoConfiguration.class, ReactiveUserDetailsServiceAutoConfiguration.class, - LemonCommonsReactiveAutoConfiguration.class}) -@ComponentScan(basePackageClasses=VersionExceptionHandler.class) + LemonCommonsMongoAutoConfiguration.class}) public class LemonReactiveAutoConfiguration { private static final Log log = LogFactory.getLog(LemonReactiveAutoConfiguration.class); diff --git a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveService.java b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveService.java index 236a5b14..dd98858b 100644 --- a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveService.java +++ b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveService.java @@ -31,6 +31,7 @@ import com.naturalprogrammer.spring.lemon.commons.security.UserDto; import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; import com.naturalprogrammer.spring.lemon.commons.util.UserUtils; +import com.naturalprogrammer.spring.lemon.commonsmongo.LecmUtils; import com.naturalprogrammer.spring.lemon.commonsreactive.util.LecrUtils; import com.naturalprogrammer.spring.lemon.exceptions.util.LexUtils; import com.naturalprogrammer.spring.lemonreactive.domain.AbstractMongoUser; @@ -504,7 +505,7 @@ protected U updateUser(U user, Optional currentUser, String patch) { U updatedUser = LecrUtils.applyPatch(user, patch); // create a patched form LexUtils.validate("updatedUser", updatedUser, UserUtils.UpdateValidation.class); - LerUtils.ensureCorrectVersion(user, updatedUser); + LecmUtils.ensureCorrectVersion(user, updatedUser); updateUserFields(user, updatedUser, currentUser.get()); diff --git a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/domain/AbstractMongoUser.java b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/domain/AbstractMongoUser.java index c8ea7d03..20e56f0d 100644 --- a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/domain/AbstractMongoUser.java +++ b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/domain/AbstractMongoUser.java @@ -14,6 +14,7 @@ import com.naturalprogrammer.spring.lemon.commons.util.UserUtils; import com.naturalprogrammer.spring.lemon.commons.validation.Captcha; import com.naturalprogrammer.spring.lemon.commons.validation.Password; +import com.naturalprogrammer.spring.lemon.commonsmongo.AbstractDocument; import com.naturalprogrammer.spring.lemonreactive.validation.UniqueEmail; import lombok.Getter; diff --git a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/util/LerUtils.java b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/util/LerUtils.java index ac69d749..f9daba48 100644 --- a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/util/LerUtils.java +++ b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/util/LerUtils.java @@ -7,8 +7,6 @@ import com.naturalprogrammer.spring.lemon.commons.security.JwtService; import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; -import com.naturalprogrammer.spring.lemon.exceptions.VersionException; -import com.naturalprogrammer.spring.lemonreactive.domain.AbstractDocument; import com.naturalprogrammer.spring.lemonreactive.domain.AbstractMongoUser; import com.nimbusds.jwt.JWTClaimsSet; @@ -36,18 +34,4 @@ void ensureCredentialsUpToDate(JWTClaimsSet claims, U user) { LecUtils.ensureCredentials(issueTime >= user.getCredentialsUpdatedMillis(), "com.naturalprogrammer.spring.obsoleteToken"); } - - /** - * Throws a VersionException if the versions of the - * given entities aren't same. - * - * @param original - * @param updated - */ - public static - void ensureCorrectVersion(AbstractDocument original, AbstractDocument updated) { - - if (original.getVersion() != updated.getVersion()) - throw new VersionException(original.getClass().getSimpleName(), original.getId().toString()); - } } From 4210511d97bb2751f4fb0b419468db31d674670e Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Sat, 29 Sep 2018 10:23:54 +0530 Subject: [PATCH 053/116] Segregated the code properly into the newly added code --- lemon-demo-angularjs/package.json | 1 + .../spring/lemondemo/entities/User.java | 2 +- .../spring/lemondemo/services/MyService.java | 5 +- .../spring/lemondemo/UpdateUserMvcTests.java | 2 +- .../spring/lemon/commonsjpa/LemonEntity.java | 58 +++++++++++++++++++ .../lemon/commonsmongo/AbstractDocument.java | 10 ++-- ...LemonCommonsReactiveAutoConfiguration.java | 17 ++++++ .../security/LemonReactiveAuditorAware.java | 35 +++++++++++ .../LemonCommonsWebAutoConfiguration.java | 15 +++++ .../security/LemonWebAuditorAware.java | 31 ++++++++++ .../lemon/commonsweb/util/LecwUtils.java | 1 - .../commons/domain/AbstractAuditorAware.java | 45 ++++++++++++++ .../lemon/commons/domain/IdConverter.java | 9 +++ .../spring/lemon/LemonAutoConfiguration.java | 24 +++----- .../spring/lemon/LemonController.java | 2 +- .../spring/lemon/LemonService.java | 4 +- .../spring/lemon/domain/AbstractUser.java | 7 +-- .../lemon/domain/AbstractUserRepository.java | 2 +- .../lemon/domain/LemonAuditorAware.java | 45 -------------- .../spring/lemon/domain/LemonEntity.java | 33 ----------- .../spring/lemon/domain/VersionedEntity.java | 25 -------- .../JpaJwtAuthenticationProvider.java | 2 +- .../security/LemonOAuth2UserService.java | 2 +- .../security/LemonUserDetailsService.java | 2 +- .../spring/lemon/util/LemonUtils.java | 10 ++-- .../src/main/resources/META-INF/orm.xml | 18 ------ .../LemonReactiveAutoConfiguration.java | 7 +++ 27 files changed, 251 insertions(+), 163 deletions(-) create mode 100644 spring-lemon-commons-jpa/src/main/java/com/naturalprogrammer/spring/lemon/commonsjpa/LemonEntity.java create mode 100644 spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/security/LemonReactiveAuditorAware.java create mode 100644 spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/security/LemonWebAuditorAware.java create mode 100644 spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/domain/AbstractAuditorAware.java create mode 100644 spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/domain/IdConverter.java delete mode 100644 spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/domain/LemonAuditorAware.java delete mode 100644 spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/domain/LemonEntity.java delete mode 100644 spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/domain/VersionedEntity.java delete mode 100644 spring-lemon-jpa/src/main/resources/META-INF/orm.xml diff --git a/lemon-demo-angularjs/package.json b/lemon-demo-angularjs/package.json index 973999cb..4f783b6f 100644 --- a/lemon-demo-angularjs/package.json +++ b/lemon-demo-angularjs/package.json @@ -2,6 +2,7 @@ "name": "angularsample", "version": "0.0.0", "dependencies": { + "natives": "^1.1.5", "wiredep": "^2.2.2" }, "repository": {}, diff --git a/lemon-demo-jpa/src/main/java/com/naturalprogrammer/spring/lemondemo/entities/User.java b/lemon-demo-jpa/src/main/java/com/naturalprogrammer/spring/lemondemo/entities/User.java index b1875d78..357af53f 100644 --- a/lemon-demo-jpa/src/main/java/com/naturalprogrammer/spring/lemondemo/entities/User.java +++ b/lemon-demo-jpa/src/main/java/com/naturalprogrammer/spring/lemondemo/entities/User.java @@ -19,7 +19,7 @@ @Entity @Table(name="usr") @Getter @Setter @NoArgsConstructor -public class User extends AbstractUser { +public class User extends AbstractUser { private static final long serialVersionUID = 2716710947175132319L; diff --git a/lemon-demo-jpa/src/main/java/com/naturalprogrammer/spring/lemondemo/services/MyService.java b/lemon-demo-jpa/src/main/java/com/naturalprogrammer/spring/lemondemo/services/MyService.java index 2d14457b..f8fe2bb8 100644 --- a/lemon-demo-jpa/src/main/java/com/naturalprogrammer/spring/lemondemo/services/MyService.java +++ b/lemon-demo-jpa/src/main/java/com/naturalprogrammer/spring/lemondemo/services/MyService.java @@ -39,8 +39,7 @@ protected User createAdminUser() { User user = super.createAdminUser(); user.setName(ADMIN_NAME); return user; - } - + } @Override public void fillAdditionalFields(String registrationId, User user, Map attributes) { @@ -65,7 +64,7 @@ public void fillAdditionalFields(String registrationId, User user, Map extends AbstractPersistable implements PermissionEvaluatorEntity { + + private static final long serialVersionUID = -8151190931948396443L; + + @CreatedBy + private ID createdById; + + @CreatedDate + private Instant createdDate; + + @LastModifiedBy + private ID lastModifiedById; + + @LastModifiedDate + private Instant lastModifiedDate; + + @Version + private long version; + + /** + * Whether the given user has the given permission for + * this entity. Override this method where you need. + */ + @Override + public boolean hasPermission(UserDto user, String permission) { + return false; + } + +} diff --git a/spring-lemon-commons-mongo/src/main/java/com/naturalprogrammer/spring/lemon/commonsmongo/AbstractDocument.java b/spring-lemon-commons-mongo/src/main/java/com/naturalprogrammer/spring/lemon/commonsmongo/AbstractDocument.java index 5e4cc5a6..4fd85efa 100644 --- a/spring-lemon-commons-mongo/src/main/java/com/naturalprogrammer/spring/lemon/commonsmongo/AbstractDocument.java +++ b/spring-lemon-commons-mongo/src/main/java/com/naturalprogrammer/spring/lemon/commonsmongo/AbstractDocument.java @@ -25,19 +25,19 @@ public abstract class AbstractDocument implements Permi protected ID id; @CreatedBy - protected ID createdBy; + private ID createdBy; @CreatedDate - protected Instant createdDate; + private Instant createdDate; @LastModifiedBy - protected ID lastModifiedBy; + private ID lastModifiedBy; @LastModifiedDate - protected Instant lastModifiedDate; + private Instant lastModifiedDate; @Version - protected long version; + private long version; /** * Whether the given user has the given permission for diff --git a/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/LemonCommonsReactiveAutoConfiguration.java b/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/LemonCommonsReactiveAutoConfiguration.java index 80405991..507cdf11 100644 --- a/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/LemonCommonsReactiveAutoConfiguration.java +++ b/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/LemonCommonsReactiveAutoConfiguration.java @@ -1,5 +1,7 @@ package com.naturalprogrammer.spring.lemon.commonsreactive; +import java.io.Serializable; + import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.bson.types.ObjectId; @@ -13,6 +15,7 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; +import org.springframework.data.domain.AuditorAware; import org.springframework.security.access.PermissionEvaluator; import org.springframework.security.access.expression.AbstractSecurityExpressionHandler; import org.springframework.security.config.annotation.method.configuration.EnableReactiveMethodSecurity; @@ -27,6 +30,7 @@ import com.naturalprogrammer.spring.lemon.commonsreactive.exceptions.LemonReactiveErrorAttributes; import com.naturalprogrammer.spring.lemon.commonsreactive.exceptions.handlers.VersionExceptionHandler; import com.naturalprogrammer.spring.lemon.commonsreactive.security.LemonCommonsReactiveSecurityConfig; +import com.naturalprogrammer.spring.lemon.commonsreactive.security.LemonReactiveAuditorAware; import com.naturalprogrammer.spring.lemon.commonsreactive.security.LemonReactiveCorsConfig; import com.naturalprogrammer.spring.lemon.commonsreactive.util.LecrUtils; import com.naturalprogrammer.spring.lemon.exceptions.ErrorResponseComposer; @@ -110,6 +114,19 @@ public SimpleModule objectIdModule() { } + /** + * Configures an Auditor Aware if missing + */ + @Bean + @ConditionalOnMissingBean(AuditorAware.class) + public + AuditorAware auditorAware() { + + log.info("Configuring LemonAuditorAware"); + return new LemonReactiveAuditorAware(); + } + + /** * Configures LeeUtils */ diff --git a/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/security/LemonReactiveAuditorAware.java b/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/security/LemonReactiveAuditorAware.java new file mode 100644 index 00000000..abab5336 --- /dev/null +++ b/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/security/LemonReactiveAuditorAware.java @@ -0,0 +1,35 @@ +package com.naturalprogrammer.spring.lemon.commonsreactive.security; + +import java.io.Serializable; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import com.naturalprogrammer.spring.lemon.commons.domain.AbstractAuditorAware; +import com.naturalprogrammer.spring.lemon.commons.security.UserDto; + +/** + * Needed for auto-filling of the + * AbstractAuditable columns of AbstractUser + * + * @author Sanjay Patel + */ +public class LemonReactiveAuditorAware +extends AbstractAuditorAware { + + private static final Log log = LogFactory.getLog(LemonReactiveAuditorAware.class); + + public LemonReactiveAuditorAware() { + log.info("Created"); + } + + @Override + protected UserDto currentUser() { + + // TODO: Can't return a mono, as below + // So, sorry, no reactive auditing until Spring Data supports it + // return LecrUtils.currentUser(); + + return null; + } +} diff --git a/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/LemonCommonsWebAutoConfiguration.java b/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/LemonCommonsWebAutoConfiguration.java index 900c84d2..43f58dae 100644 --- a/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/LemonCommonsWebAutoConfiguration.java +++ b/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/LemonCommonsWebAutoConfiguration.java @@ -1,5 +1,6 @@ package com.naturalprogrammer.spring.lemon.commonsweb; +import java.io.Serializable; import java.util.List; import org.apache.commons.logging.Log; @@ -18,6 +19,7 @@ import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.data.domain.AuditorAware; import org.springframework.data.web.config.EnableSpringDataWebSupport; import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; @@ -31,6 +33,7 @@ import com.naturalprogrammer.spring.lemon.commonsweb.exceptions.LemonErrorController; import com.naturalprogrammer.spring.lemon.commonsweb.security.JwtAuthenticationProvider; import com.naturalprogrammer.spring.lemon.commonsweb.security.LemonCorsConfig; +import com.naturalprogrammer.spring.lemon.commonsweb.security.LemonWebAuditorAware; import com.naturalprogrammer.spring.lemon.commonsweb.security.LemonWebSecurityConfig; import com.naturalprogrammer.spring.lemon.commonsweb.util.LecwUtils; import com.naturalprogrammer.spring.lemon.exceptions.ErrorResponseComposer; @@ -150,6 +153,18 @@ public LemonWebSecurityConfig lemonSecurityConfig() { return new LemonWebSecurityConfig(); } + /** + * Configures an Auditor Aware if missing + */ + @Bean + @ConditionalOnMissingBean(AuditorAware.class) + public + AuditorAware auditorAware() { + + log.info("Configuring LemonAuditorAware"); + return new LemonWebAuditorAware(); + } + /** * Configures LemonUtils */ diff --git a/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/security/LemonWebAuditorAware.java b/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/security/LemonWebAuditorAware.java new file mode 100644 index 00000000..864ee0fb --- /dev/null +++ b/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/security/LemonWebAuditorAware.java @@ -0,0 +1,31 @@ +package com.naturalprogrammer.spring.lemon.commonsweb.security; + +import java.io.Serializable; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import com.naturalprogrammer.spring.lemon.commons.domain.AbstractAuditorAware; +import com.naturalprogrammer.spring.lemon.commons.security.UserDto; +import com.naturalprogrammer.spring.lemon.commonsweb.util.LecwUtils; + +/** + * Needed for auto-filling of the + * AbstractAuditable columns of AbstractUser + * + * @author Sanjay Patel + */ +public class LemonWebAuditorAware +extends AbstractAuditorAware { + + private static final Log log = LogFactory.getLog(LemonWebAuditorAware.class); + + public LemonWebAuditorAware() { + log.info("Created"); + } + + @Override + protected UserDto currentUser() { + return LecwUtils.currentUser(); + } +} diff --git a/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/util/LecwUtils.java b/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/util/LecwUtils.java index 1801d6d4..9635a192 100644 --- a/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/util/LecwUtils.java +++ b/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/util/LecwUtils.java @@ -1,6 +1,5 @@ package com.naturalprogrammer.spring.lemon.commonsweb.util; -import java.io.Serializable; import java.util.Optional; import javax.servlet.http.Cookie; diff --git a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/domain/AbstractAuditorAware.java b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/domain/AbstractAuditorAware.java new file mode 100644 index 00000000..e6604a5f --- /dev/null +++ b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/domain/AbstractAuditorAware.java @@ -0,0 +1,45 @@ +package com.naturalprogrammer.spring.lemon.commons.domain; + +import java.io.Serializable; +import java.util.Optional; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.AuditorAware; + +import com.naturalprogrammer.spring.lemon.commons.security.UserDto; + +/** + * Needed for auto-filling of the + * AbstractAuditable columns of AbstractUser + * + * @author Sanjay Patel + */ +public abstract class AbstractAuditorAware +implements AuditorAware { + + private static final Log log = LogFactory.getLog(AbstractAuditorAware.class); + + private IdConverter idConverter; + + @Autowired + public void setIdConverter(IdConverter idConverter) { + + this.idConverter = idConverter; + log.info("Created"); + } + + protected abstract UserDto currentUser(); + + @Override + public Optional getCurrentAuditor() { + + UserDto user = currentUser(); + + if (user == null) + return Optional.empty(); + + return Optional.of(idConverter.toId(user.getId())); + } +} diff --git a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/domain/IdConverter.java b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/domain/IdConverter.java new file mode 100644 index 00000000..e6c8ced8 --- /dev/null +++ b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/domain/IdConverter.java @@ -0,0 +1,9 @@ +package com.naturalprogrammer.spring.lemon.commons.domain; + +import java.io.Serializable; + +@FunctionalInterface +public interface IdConverter { + + ID toId(String id); +} diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/LemonAutoConfiguration.java b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/LemonAutoConfiguration.java index ef5a3c3f..03b3a6c9 100644 --- a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/LemonAutoConfiguration.java +++ b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/LemonAutoConfiguration.java @@ -9,7 +9,6 @@ import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.data.domain.AuditorAware; import org.springframework.data.jpa.repository.config.EnableJpaAuditing; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.crypto.password.PasswordEncoder; @@ -19,6 +18,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.naturalprogrammer.spring.lemon.commons.LemonProperties; +import com.naturalprogrammer.spring.lemon.commons.domain.IdConverter; import com.naturalprogrammer.spring.lemon.commons.security.JwtService; import com.naturalprogrammer.spring.lemon.commons.validation.RetypePasswordValidator; import com.naturalprogrammer.spring.lemon.commonsjpa.LemonCommonsJpaAutoConfiguration; @@ -26,7 +26,6 @@ import com.naturalprogrammer.spring.lemon.commonsweb.security.LemonWebSecurityConfig; import com.naturalprogrammer.spring.lemon.domain.AbstractUser; import com.naturalprogrammer.spring.lemon.domain.AbstractUserRepository; -import com.naturalprogrammer.spring.lemon.domain.LemonAuditorAware; import com.naturalprogrammer.spring.lemon.security.JpaJwtAuthenticationProvider; import com.naturalprogrammer.spring.lemon.security.LemonAuthenticationSuccessHandler; import com.naturalprogrammer.spring.lemon.security.LemonJpaSecurityConfig; @@ -55,18 +54,13 @@ public LemonAutoConfiguration() { log.info("Created"); } - /** - * Configures an Auditor Aware if missing - */ @Bean - @ConditionalOnMissingBean(AuditorAware.class) - public , ID extends Serializable> - AuditorAware auditorAware(LemonService lemonService) { - - log.info("Configuring LemonAuditorAware"); - return new LemonAuditorAware(lemonService); + @ConditionalOnMissingBean(IdConverter.class) + public + IdConverter idConverter(LemonService lemonService) { + return id -> lemonService.toId(id); } - + /** * Configures AuthenticationSuccessHandler if missing */ @@ -118,7 +112,7 @@ public AuthenticationFailureHandler authenticationFailureHandler() { */ @Bean @ConditionalOnMissingBean(UserDetailsService.class) - public , ID extends Serializable> + public , ID extends Serializable> UserDetailsService userDetailService(AbstractUserRepository userRepository) { log.info("Configuring LemonUserDetailsService"); @@ -141,7 +135,7 @@ public LemonOidcUserService lemonOidcUserService(LemonOAuth2UserService le */ @Bean @ConditionalOnMissingBean(LemonOAuth2UserService.class) - public , ID extends Serializable> + public , ID extends Serializable> LemonOAuth2UserService lemonOAuth2UserService( LemonUserDetailsService userDetailsService, LemonService lemonService, @@ -156,7 +150,7 @@ LemonOAuth2UserService lemonOAuth2UserService( */ @Bean @ConditionalOnMissingBean(JwtAuthenticationProvider.class) - public , ID extends Serializable> + public , ID extends Serializable> JwtAuthenticationProvider jwtAuthenticationProvider( JwtService jwtService, LemonUserDetailsService userDetailsService) { diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/LemonController.java b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/LemonController.java index e9fe7c2b..77c5537d 100644 --- a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/LemonController.java +++ b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/LemonController.java @@ -41,7 +41,7 @@ * @author Sanjay Patel */ public abstract class LemonController - , ID extends Serializable> { + , ID extends Serializable> { private static final Log log = LogFactory.getLog(LemonController.class); diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/LemonService.java b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/LemonService.java index 487659ff..68f41a80 100644 --- a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/LemonService.java +++ b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/LemonService.java @@ -53,7 +53,7 @@ @Validated @Transactional(propagation=Propagation.SUPPORTS, readOnly=true) public abstract class LemonService - , ID extends Serializable> { + , ID extends Serializable> { private static final Log log = LogFactory.getLog(LemonService.class); @@ -501,7 +501,7 @@ public String changePassword(U user, @Valid ChangePasswordForm changePasswordFor } - protected abstract ID toId(String id); + public abstract ID toId(String id); /** * Updates the fields of the users. Override this if you have more fields. diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/domain/AbstractUser.java b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/domain/AbstractUser.java index d8aa8eef..3dce1604 100644 --- a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/domain/AbstractUser.java +++ b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/domain/AbstractUser.java @@ -18,6 +18,7 @@ import com.naturalprogrammer.spring.lemon.commons.util.UserUtils; import com.naturalprogrammer.spring.lemon.commons.validation.Captcha; import com.naturalprogrammer.spring.lemon.commons.validation.Password; +import com.naturalprogrammer.spring.lemon.commonsjpa.LemonEntity; import com.naturalprogrammer.spring.lemon.validation.UniqueEmail; import lombok.Getter; @@ -31,10 +32,8 @@ */ @Getter @Setter @MappedSuperclass -public class AbstractUser - , - ID extends Serializable> -extends VersionedEntity { +public class AbstractUser +extends LemonEntity { // email @JsonView(UserUtils.SignupInput.class) diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/domain/AbstractUserRepository.java b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/domain/AbstractUserRepository.java index 9bf138d8..fb7bb065 100644 --- a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/domain/AbstractUserRepository.java +++ b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/domain/AbstractUserRepository.java @@ -14,7 +14,7 @@ */ @NoRepositoryBean public interface AbstractUserRepository - , ID extends Serializable> + , ID extends Serializable> extends JpaRepository { Optional findByEmail(String email); diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/domain/LemonAuditorAware.java b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/domain/LemonAuditorAware.java deleted file mode 100644 index 6da5e391..00000000 --- a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/domain/LemonAuditorAware.java +++ /dev/null @@ -1,45 +0,0 @@ -package com.naturalprogrammer.spring.lemon.domain; - -import java.io.Serializable; -import java.util.Optional; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.springframework.data.domain.AuditorAware; - -import com.naturalprogrammer.spring.lemon.LemonService; -import com.naturalprogrammer.spring.lemon.commons.security.UserDto; -import com.naturalprogrammer.spring.lemon.commonsweb.util.LecwUtils; - -/** - * Needed for auto-filling of the - * AbstractAuditable columns of AbstractUser - * - * @author Sanjay Patel - */ -public class LemonAuditorAware - , - ID extends Serializable> -implements AuditorAware { - - private static final Log log = LogFactory.getLog(LemonAuditorAware.class); - - private LemonService lemonService; - - public LemonAuditorAware(LemonService lemonService) { - - this.lemonService = lemonService; - log.info("Created"); - } - - @Override - public Optional getCurrentAuditor() { - - UserDto currentUser = LecwUtils.currentUser(); - - if (currentUser == null) - return Optional.empty(); - - return lemonService.findUserById(currentUser.getId()); - } -} diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/domain/LemonEntity.java b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/domain/LemonEntity.java deleted file mode 100644 index 8c4085b7..00000000 --- a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/domain/LemonEntity.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.naturalprogrammer.spring.lemon.domain; - -import java.io.Serializable; - -import javax.persistence.MappedSuperclass; - -import org.springframework.data.jpa.domain.AbstractAuditable; - -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.naturalprogrammer.spring.lemon.commons.security.PermissionEvaluatorEntity; -import com.naturalprogrammer.spring.lemon.commons.security.UserDto; - -/** - * Base class for all entities. - * - * @author Sanjay Patel - */ -@MappedSuperclass -@JsonIgnoreProperties({ "createdBy", "lastModifiedBy", "createdDate", "lastModifiedDate" }) -public class LemonEntity, ID extends Serializable> extends AbstractAuditable implements PermissionEvaluatorEntity { - - private static final long serialVersionUID = -8151190931948396443L; - - /** - * Whether the given user has the given permission for - * this entity. Override this method where you need. - */ - @Override - public boolean hasPermission(UserDto user, String permission) { - return false; - } - -} diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/domain/VersionedEntity.java b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/domain/VersionedEntity.java deleted file mode 100644 index ae495ec2..00000000 --- a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/domain/VersionedEntity.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.naturalprogrammer.spring.lemon.domain; - -import java.io.Serializable; - -import javax.persistence.MappedSuperclass; -import javax.persistence.Version; - -import lombok.Getter; -import lombok.Setter; - - -/** - * Base class for all entities needing optimistic locking. - * - * @author Sanjay Patel - */ -@MappedSuperclass -@Getter @Setter -public abstract class VersionedEntity, ID extends Serializable> extends LemonEntity { - - private static final long serialVersionUID = 4310555782328370192L; - - @Version - private Long version; -} diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/JpaJwtAuthenticationProvider.java b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/JpaJwtAuthenticationProvider.java index 02102ae3..eefc7411 100644 --- a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/JpaJwtAuthenticationProvider.java +++ b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/JpaJwtAuthenticationProvider.java @@ -17,7 +17,7 @@ * Authentication provider for JWT token authentication */ public class JpaJwtAuthenticationProvider -, ID extends Serializable> extends JwtAuthenticationProvider { +, ID extends Serializable> extends JwtAuthenticationProvider { private static final Log log = LogFactory.getLog(JpaJwtAuthenticationProvider.class); diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonOAuth2UserService.java b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonOAuth2UserService.java index 1ca8276a..4ec99dc4 100644 --- a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonOAuth2UserService.java +++ b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonOAuth2UserService.java @@ -22,7 +22,7 @@ /** * Logs in or registers a user after OAuth2 SignIn/Up */ -public class LemonOAuth2UserService, ID extends Serializable> extends DefaultOAuth2UserService { +public class LemonOAuth2UserService, ID extends Serializable> extends DefaultOAuth2UserService { private static final Log log = LogFactory.getLog(LemonOAuth2UserService.class); diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonUserDetailsService.java b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonUserDetailsService.java index 67889844..f0d46230 100644 --- a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonUserDetailsService.java +++ b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonUserDetailsService.java @@ -19,7 +19,7 @@ * @author Sanjay Patel */ public class LemonUserDetailsService - , ID extends Serializable> + , ID extends Serializable> implements UserDetailsService { private static final Log log = LogFactory.getLog(LemonUserDetailsService.class); diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/util/LemonUtils.java b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/util/LemonUtils.java index c2cfc9c7..017d13fc 100644 --- a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/util/LemonUtils.java +++ b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/util/LemonUtils.java @@ -11,8 +11,8 @@ import com.naturalprogrammer.spring.lemon.commons.security.JwtService; import com.naturalprogrammer.spring.lemon.commons.security.LemonPrincipal; import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; +import com.naturalprogrammer.spring.lemon.commonsjpa.LemonEntity; import com.naturalprogrammer.spring.lemon.domain.AbstractUser; -import com.naturalprogrammer.spring.lemon.domain.VersionedEntity; import com.naturalprogrammer.spring.lemon.exceptions.VersionException; import com.nimbusds.jwt.JWTClaimsSet; @@ -36,7 +36,7 @@ public LemonUtils() { * * @param user */ - public static , ID extends Serializable> + public static , ID extends Serializable> void login(U user) { LemonPrincipal principal = new LemonPrincipal(user.toUserDto()); @@ -56,8 +56,8 @@ void login(U user) { * @param original * @param updated */ - public static , ID extends Serializable> - void ensureCorrectVersion(VersionedEntity original, VersionedEntity updated) { + public static , ID extends Serializable> + void ensureCorrectVersion(LemonEntity original, LemonEntity updated) { if (original.getVersion() != updated.getVersion()) throw new VersionException(original.getClass().getSimpleName(), original.getId().toString()); @@ -68,7 +68,7 @@ void ensureCorrectVersion(VersionedEntity original, VersionedEntity * Throws BadCredentialsException if * user's credentials were updated after the JWT was issued */ - public static , ID extends Serializable> + public static , ID extends Serializable> void ensureCredentialsUpToDate(JWTClaimsSet claims, U user) { long issueTime = (long) claims.getClaim(JwtService.LEMON_IAT); diff --git a/spring-lemon-jpa/src/main/resources/META-INF/orm.xml b/spring-lemon-jpa/src/main/resources/META-INF/orm.xml deleted file mode 100644 index a5a5f13d..00000000 --- a/spring-lemon-jpa/src/main/resources/META-INF/orm.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - JPA - - - - - - - - - - diff --git a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveAutoConfiguration.java b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveAutoConfiguration.java index 7fc2ca9b..c8997545 100644 --- a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveAutoConfiguration.java +++ b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveAutoConfiguration.java @@ -11,6 +11,7 @@ import org.springframework.context.annotation.Configuration; import org.springframework.security.core.userdetails.UserDetailsService; +import com.naturalprogrammer.spring.lemon.commons.domain.IdConverter; import com.naturalprogrammer.spring.lemon.commons.security.JwtService; import com.naturalprogrammer.spring.lemon.commonsmongo.LemonCommonsMongoAutoConfiguration; import com.naturalprogrammer.spring.lemon.exceptions.util.LexUtils; @@ -32,6 +33,12 @@ public LemonReactiveAutoConfiguration() { log.info("Created"); } + @Bean + @ConditionalOnMissingBean(IdConverter.class) + public + IdConverter idConverter(LemonReactiveService lemonService) { + return id -> lemonService.toId(id); + } @Bean @ConditionalOnMissingBean(LemonReactiveSecurityConfig.class) From 0cb91859c349be3a6b911688c389ea77bb1bc98c Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Sat, 29 Sep 2018 17:54:32 +0530 Subject: [PATCH 054/116] Fixed date data types --- .../spring/lemon/commonsjpa/LemonEntity.java | 9 +++++++-- .../spring/lemon/commonsmongo/AbstractDocument.java | 5 +++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/spring-lemon-commons-jpa/src/main/java/com/naturalprogrammer/spring/lemon/commonsjpa/LemonEntity.java b/spring-lemon-commons-jpa/src/main/java/com/naturalprogrammer/spring/lemon/commonsjpa/LemonEntity.java index af29fde6..1c1891c0 100644 --- a/spring-lemon-commons-jpa/src/main/java/com/naturalprogrammer/spring/lemon/commonsjpa/LemonEntity.java +++ b/spring-lemon-commons-jpa/src/main/java/com/naturalprogrammer/spring/lemon/commonsjpa/LemonEntity.java @@ -2,8 +2,11 @@ import java.io.Serializable; import java.time.Instant; +import java.util.Date; import javax.persistence.MappedSuperclass; +import javax.persistence.Temporal; +import javax.persistence.TemporalType; import javax.persistence.Version; import org.springframework.data.annotation.CreatedBy; @@ -35,13 +38,15 @@ public class LemonEntity extends AbstractPersistable implements Permi private ID createdBy; @CreatedDate - private Instant createdDate; + private Date createdDate; @LastModifiedBy private ID lastModifiedBy; @LastModifiedDate - private Instant lastModifiedDate; + private Date lastModifiedDate; @Version private long version; From 2b4e97b58f74b444ff80c7d4c3b3cf05bd509c7f Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Sun, 30 Sep 2018 20:03:05 +0530 Subject: [PATCH 055/116] Changed token authentication as discussed in issue #24 --- .../app/scripts/services/user-service.js | 4 +- .../spring/lemon/commonsjpa/LemonEntity.java | 1 - .../lemon/commonsmongo/AbstractDocument.java | 1 - .../LemonCommonsReactiveSecurityConfig.java | 6 +- .../LemonCommonsWebAutoConfiguration.java | 14 --- .../security/JwtAuthenticationProvider.java | 65 ------------ ...onCommonsWebTokenAuthenticationFilter.java | 100 ++++++++++++++++++ .../LemonTokenAuthenticationFilter.java | 81 -------------- .../security/LemonWebSecurityConfig.java | 22 ++-- .../security/JwtAuthenticationToken.java | 42 -------- .../spring/lemon/LemonAutoConfiguration.java | 18 +--- .../security/LemonJpaSecurityConfig.java | 21 ++-- ...=> LemonJpaTokenAuthenticationFilter.java} | 20 ++-- 13 files changed, 130 insertions(+), 265 deletions(-) delete mode 100644 spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/security/JwtAuthenticationProvider.java create mode 100644 spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/security/LemonCommonsWebTokenAuthenticationFilter.java delete mode 100644 spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/security/LemonTokenAuthenticationFilter.java delete mode 100644 spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/JwtAuthenticationToken.java rename spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/{JpaJwtAuthenticationProvider.java => LemonJpaTokenAuthenticationFilter.java} (62%) diff --git a/lemon-demo-angularjs/app/scripts/services/user-service.js b/lemon-demo-angularjs/app/scripts/services/user-service.js index 65112e6a..7f06c10e 100644 --- a/lemon-demo-angularjs/app/scripts/services/user-service.js +++ b/lemon-demo-angularjs/app/scripts/services/user-service.js @@ -24,8 +24,8 @@ angular.module('angularSampleApp') this.goodUser = !(this.unverified || this.blocked); this.goodAdmin = this.admin && this.goodUser; - this.editable = authService.isAuthenticated() && (this.id === authService.user.id || authService.isGoodAdmin()); - this.rolesEditable = authService.isGoodAdmin() && this.id !== authService.user.id; + this.editable = authService.isAuthenticated() && (this.id == authService.user.id || authService.isGoodAdmin()); + this.rolesEditable = authService.isGoodAdmin() && this.id != authService.user.id; }; User.prototype.hasRole = function(role) { diff --git a/spring-lemon-commons-jpa/src/main/java/com/naturalprogrammer/spring/lemon/commonsjpa/LemonEntity.java b/spring-lemon-commons-jpa/src/main/java/com/naturalprogrammer/spring/lemon/commonsjpa/LemonEntity.java index 1c1891c0..37ac4f45 100644 --- a/spring-lemon-commons-jpa/src/main/java/com/naturalprogrammer/spring/lemon/commonsjpa/LemonEntity.java +++ b/spring-lemon-commons-jpa/src/main/java/com/naturalprogrammer/spring/lemon/commonsjpa/LemonEntity.java @@ -1,7 +1,6 @@ package com.naturalprogrammer.spring.lemon.commonsjpa; import java.io.Serializable; -import java.time.Instant; import java.util.Date; import javax.persistence.MappedSuperclass; diff --git a/spring-lemon-commons-mongo/src/main/java/com/naturalprogrammer/spring/lemon/commonsmongo/AbstractDocument.java b/spring-lemon-commons-mongo/src/main/java/com/naturalprogrammer/spring/lemon/commonsmongo/AbstractDocument.java index d38b736e..46828ef0 100644 --- a/spring-lemon-commons-mongo/src/main/java/com/naturalprogrammer/spring/lemon/commonsmongo/AbstractDocument.java +++ b/spring-lemon-commons-mongo/src/main/java/com/naturalprogrammer/spring/lemon/commonsmongo/AbstractDocument.java @@ -1,7 +1,6 @@ package com.naturalprogrammer.spring.lemon.commonsmongo; import java.io.Serializable; -import java.time.Instant; import java.util.Date; import org.springframework.data.annotation.CreatedBy; diff --git a/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/security/LemonCommonsReactiveSecurityConfig.java b/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/security/LemonCommonsReactiveSecurityConfig.java index 2371c6dd..573451a3 100644 --- a/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/security/LemonCommonsReactiveSecurityConfig.java +++ b/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/security/LemonCommonsReactiveSecurityConfig.java @@ -7,6 +7,7 @@ import org.springframework.http.HttpHeaders; import org.springframework.security.authentication.AuthenticationCredentialsNotFoundException; import org.springframework.security.authentication.ReactiveAuthenticationManager; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.config.web.server.SecurityWebFiltersOrder; import org.springframework.security.config.web.server.ServerHttpSecurity; import org.springframework.security.core.Authentication; @@ -18,7 +19,6 @@ import org.springframework.security.web.server.context.NoOpServerSecurityContextRepository; import org.springframework.web.server.ServerWebExchange; -import com.naturalprogrammer.spring.lemon.commons.security.JwtAuthenticationToken; import com.naturalprogrammer.spring.lemon.commons.security.JwtService; import com.naturalprogrammer.spring.lemon.commons.security.LemonPrincipal; import com.naturalprogrammer.spring.lemon.commons.security.UserDto; @@ -100,7 +100,7 @@ protected ReactiveAuthenticationManager tokenAuthenticationManager() { return userDtoMono.map(LemonPrincipal::new) .doOnNext(LemonPrincipal::eraseCredentials) - .map(principal -> new JwtAuthenticationToken(principal, token, principal.getAuthorities())); + .map(principal -> new UsernamePasswordAuthenticationToken(principal, token, principal.getAuthorities())); }; } @@ -125,7 +125,7 @@ protected Function> tokenAuthenticationC if(authorization == null || !authorization.startsWith(LecUtils.TOKEN_PREFIX)) return Mono.empty(); - return Mono.just(new JwtAuthenticationToken(authorization.substring(LecUtils.TOKEN_PREFIX_LENGTH))); + return Mono.just(new UsernamePasswordAuthenticationToken(null, authorization.substring(LecUtils.TOKEN_PREFIX_LENGTH))); }; } diff --git a/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/LemonCommonsWebAutoConfiguration.java b/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/LemonCommonsWebAutoConfiguration.java index 43f58dae..7d6615b5 100644 --- a/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/LemonCommonsWebAutoConfiguration.java +++ b/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/LemonCommonsWebAutoConfiguration.java @@ -27,11 +27,9 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.naturalprogrammer.spring.lemon.commons.LemonCommonsAutoConfiguration; import com.naturalprogrammer.spring.lemon.commons.LemonProperties; -import com.naturalprogrammer.spring.lemon.commons.security.JwtService; import com.naturalprogrammer.spring.lemon.commonsweb.exceptions.DefaultExceptionHandlerControllerAdvice; import com.naturalprogrammer.spring.lemon.commonsweb.exceptions.LemonErrorAttributes; import com.naturalprogrammer.spring.lemon.commonsweb.exceptions.LemonErrorController; -import com.naturalprogrammer.spring.lemon.commonsweb.security.JwtAuthenticationProvider; import com.naturalprogrammer.spring.lemon.commonsweb.security.LemonCorsConfig; import com.naturalprogrammer.spring.lemon.commonsweb.security.LemonWebAuditorAware; import com.naturalprogrammer.spring.lemon.commonsweb.security.LemonWebSecurityConfig; @@ -130,18 +128,6 @@ public LemonCorsConfig lemonCorsConfig(LemonProperties properties) { return new LemonCorsConfig(properties); } - /** - * Configures JwtAuthenticationProvider if missing - */ - @Bean - @ConditionalOnMissingBean(JwtAuthenticationProvider.class) - public JwtAuthenticationProvider jwtAuthenticationProvider( - JwtService jwtService) { - - log.info("Configuring JwtAuthenticationProvider"); - return new JwtAuthenticationProvider(jwtService); - } - /** * Configures LemonSecurityConfig if missing */ diff --git a/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/security/JwtAuthenticationProvider.java b/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/security/JwtAuthenticationProvider.java deleted file mode 100644 index 16d7e903..00000000 --- a/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/security/JwtAuthenticationProvider.java +++ /dev/null @@ -1,65 +0,0 @@ -package com.naturalprogrammer.spring.lemon.commonsweb.security; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.springframework.security.authentication.AuthenticationCredentialsNotFoundException; -import org.springframework.security.authentication.AuthenticationProvider; -import org.springframework.security.core.Authentication; - -import com.naturalprogrammer.spring.lemon.commons.security.JwtAuthenticationToken; -import com.naturalprogrammer.spring.lemon.commons.security.JwtService; -import com.naturalprogrammer.spring.lemon.commons.security.LemonPrincipal; -import com.naturalprogrammer.spring.lemon.commons.security.UserDto; -import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; -import com.naturalprogrammer.spring.lemon.exceptions.util.LexUtils; -import com.nimbusds.jwt.JWTClaimsSet; - -/** - * Authentication provider for JWT token authentication - */ -public class JwtAuthenticationProvider implements AuthenticationProvider { - - private static final Log log = LogFactory.getLog(JwtAuthenticationProvider.class); - - private final JwtService jwtService; - - public JwtAuthenticationProvider(JwtService jwtService) { - - this.jwtService = jwtService; - log.debug("Created"); - } - - @Override - public Authentication authenticate(Authentication auth) { - - log.debug("Authenticating ..."); - - String token = (String) auth.getCredentials(); - - JWTClaimsSet claims = jwtService.parseToken(token, JwtService.AUTH_AUDIENCE); - UserDto userDto = LecUtils.getUserDto(claims); - if (userDto == null) - userDto = fetchUserDto(claims); - - LemonPrincipal principal = new LemonPrincipal(userDto); - - return new JwtAuthenticationToken(principal, token, principal.getAuthorities()); - } - - /** - * Default behaviour is to throw error. To be overridden in auth service. - * - * @param username - * @return - */ - protected UserDto fetchUserDto(JWTClaimsSet claims) { - throw new AuthenticationCredentialsNotFoundException( - LexUtils.getMessage("com.naturalprogrammer.spring.userClaimAbsent")); - } - - @Override - public boolean supports(Class authentication) { - - return (JwtAuthenticationToken.class.isAssignableFrom(authentication)); - } -} diff --git a/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/security/LemonCommonsWebTokenAuthenticationFilter.java b/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/security/LemonCommonsWebTokenAuthenticationFilter.java new file mode 100644 index 00000000..11ccccda --- /dev/null +++ b/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/security/LemonCommonsWebTokenAuthenticationFilter.java @@ -0,0 +1,100 @@ +package com.naturalprogrammer.spring.lemon.commonsweb.security; + +import java.io.IOException; + +import javax.servlet.FilterChain; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.springframework.http.HttpHeaders; +import org.springframework.security.authentication.AuthenticationCredentialsNotFoundException; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.web.filter.OncePerRequestFilter; + +import com.naturalprogrammer.spring.lemon.commons.security.JwtService; +import com.naturalprogrammer.spring.lemon.commons.security.LemonPrincipal; +import com.naturalprogrammer.spring.lemon.commons.security.UserDto; +import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; +import com.naturalprogrammer.spring.lemon.exceptions.util.LexUtils; +import com.nimbusds.jwt.JWTClaimsSet; + +/** + * Filter for token authentication + */ +public class LemonCommonsWebTokenAuthenticationFilter extends OncePerRequestFilter { + + private static final Log log = LogFactory.getLog(LemonCommonsWebTokenAuthenticationFilter.class); + + private JwtService jwtService; + + public LemonCommonsWebTokenAuthenticationFilter(JwtService jwtService) { + + this.jwtService = jwtService; + log.info("Created"); + } + + @Override + protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) + throws ServletException, IOException { + + log.debug("Inside LemonTokenAuthenticationFilter ..."); + + String header = request.getHeader(HttpHeaders.AUTHORIZATION); + + if (header != null && header.startsWith(LecUtils.TOKEN_PREFIX)) { // token present + + log.debug("Found a token"); + String token = header.substring(7); + + try { + + Authentication auth = createAuthToken(token); + SecurityContextHolder.getContext().setAuthentication(auth); + + log.debug("Token authentication successful"); + + } catch (Exception e) { + + log.debug("Token authentication failed - " + e.getMessage()); + + response.sendError(HttpServletResponse.SC_UNAUTHORIZED, + "Authentication Failed: " + e.getMessage()); + + return; + } + + } else + + log.debug("Token authentication skipped"); + + filterChain.doFilter(request, response); + } + + protected Authentication createAuthToken(String token) { + + JWTClaimsSet claims = jwtService.parseToken(token, JwtService.AUTH_AUDIENCE); + UserDto userDto = LecUtils.getUserDto(claims); + if (userDto == null) + userDto = fetchUserDto(claims); + + LemonPrincipal principal = new LemonPrincipal(userDto); + + return new UsernamePasswordAuthenticationToken(principal, token, principal.getAuthorities()); + } + + /** + * Default behaviour is to throw error. To be overridden in auth service. + * + * @param username + * @return + */ + protected UserDto fetchUserDto(JWTClaimsSet claims) { + throw new AuthenticationCredentialsNotFoundException( + LexUtils.getMessage("com.naturalprogrammer.spring.userClaimAbsent")); + } +} diff --git a/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/security/LemonTokenAuthenticationFilter.java b/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/security/LemonTokenAuthenticationFilter.java deleted file mode 100644 index 701cab21..00000000 --- a/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/security/LemonTokenAuthenticationFilter.java +++ /dev/null @@ -1,81 +0,0 @@ -package com.naturalprogrammer.spring.lemon.commonsweb.security; - -import java.io.IOException; - -import javax.servlet.FilterChain; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.springframework.http.HttpHeaders; -import org.springframework.security.authentication.AuthenticationManager; -import org.springframework.security.core.Authentication; -import org.springframework.security.core.context.SecurityContextHolder; -import org.springframework.web.filter.OncePerRequestFilter; - -import com.naturalprogrammer.spring.lemon.commons.security.JwtAuthenticationToken; -import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; - -/** - * Filter for token authentication - */ -public class LemonTokenAuthenticationFilter extends OncePerRequestFilter { - - private static final Log log = LogFactory.getLog(LemonTokenAuthenticationFilter.class); - - private AuthenticationManager authenticationManager; - - public LemonTokenAuthenticationFilter(AuthenticationManager authenticationManager) { - - this.authenticationManager = authenticationManager; - log.info("Created"); - } - - /** - * Checks if a "Bearer " token is present - */ - protected boolean tokenPresent(HttpServletRequest request) { - - String header = request.getHeader(HttpHeaders.AUTHORIZATION); - return header != null && header.startsWith(LecUtils.TOKEN_PREFIX); - } - - @Override - protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) - throws ServletException, IOException { - - log.debug("Inside LemonTokenAuthenticationFilter ..."); - - if (tokenPresent(request)) { - - log.debug("Found a token"); - - String token = request.getHeader(HttpHeaders.AUTHORIZATION).substring(7); - JwtAuthenticationToken authRequest = new JwtAuthenticationToken(token); - - try { - - Authentication auth = authenticationManager.authenticate(authRequest); - SecurityContextHolder.getContext().setAuthentication(auth); - - log.debug("Token authentication successful"); - - } catch (Exception e) { - - log.debug("Token authentication failed - " + e.getMessage()); - - response.sendError(HttpServletResponse.SC_UNAUTHORIZED, - "Authentication Failed: " + e.getMessage()); - - return; - } - - } else - - log.debug("Token authentication skipped"); - - filterChain.doFilter(request, response); - } -} diff --git a/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/security/LemonWebSecurityConfig.java b/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/security/LemonWebSecurityConfig.java index 462362f8..fbad3a0b 100644 --- a/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/security/LemonWebSecurityConfig.java +++ b/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/security/LemonWebSecurityConfig.java @@ -3,13 +3,14 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.config.http.SessionCreationPolicy; import org.springframework.security.web.authentication.Http403ForbiddenEntryPoint; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; +import com.naturalprogrammer.spring.lemon.commons.security.JwtService; + /** * Security configuration class. Extend it in the * application, and make a configuration class. Override @@ -21,12 +22,12 @@ public class LemonWebSecurityConfig extends WebSecurityConfigurerAdapter { private static final Log log = LogFactory.getLog(LemonWebSecurityConfig.class); - private JwtAuthenticationProvider jwtAuthenticationProvider; + protected JwtService jwtService; @Autowired - public void createLemonWebSecurityConfig(JwtAuthenticationProvider jwtAuthenticationProvider) { + public void createLemonWebSecurityConfig(JwtService jwtService) { - this.jwtAuthenticationProvider = jwtAuthenticationProvider; + this.jwtService = jwtService; log.info("Created"); } @@ -89,8 +90,7 @@ protected void exceptionHandling(HttpSecurity http) throws Exception { */ protected void tokenAuthentication(HttpSecurity http) throws Exception { - http.addFilterBefore(new LemonTokenAuthenticationFilter( - super.authenticationManager()), + http.addFilterBefore(new LemonCommonsWebTokenAuthenticationFilter(jwtService), UsernamePasswordAuthenticationFilter.class); } @@ -134,14 +134,4 @@ protected void authorizeRequests(HttpSecurity http) throws Exception { protected void otherConfigurations(HttpSecurity http) throws Exception { } - - - /** - * Needed for configuring JwtAuthenticationProvider - */ - @Override - protected void configure(AuthenticationManagerBuilder auth) throws Exception { - - auth.authenticationProvider(jwtAuthenticationProvider); - } } diff --git a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/JwtAuthenticationToken.java b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/JwtAuthenticationToken.java deleted file mode 100644 index 4474eb21..00000000 --- a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/JwtAuthenticationToken.java +++ /dev/null @@ -1,42 +0,0 @@ -package com.naturalprogrammer.spring.lemon.commons.security; - -import java.util.Collection; - -import org.springframework.security.authentication.AbstractAuthenticationToken; -import org.springframework.security.core.GrantedAuthority; -import org.springframework.security.core.authority.AuthorityUtils; -import org.springframework.security.core.userdetails.UserDetails; - -/** - * JWT Authentication token - */ -public class JwtAuthenticationToken extends AbstractAuthenticationToken { - - private static final long serialVersionUID = 7032335279756013130L; - - private UserDetails principal; - private String jwtToken; - - public JwtAuthenticationToken(String token) { - super(AuthorityUtils.NO_AUTHORITIES); - this.jwtToken = token; - } - - public JwtAuthenticationToken(UserDetails principal, String jwtToken, Collection authorities) { - - super(authorities); - this.principal = principal; - this.jwtToken = jwtToken; - setAuthenticated(true); - } - - @Override - public Object getCredentials() { - return jwtToken; - } - - @Override - public Object getPrincipal() { - return principal; - } -} \ No newline at end of file diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/LemonAutoConfiguration.java b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/LemonAutoConfiguration.java index 03b3a6c9..cac71cef 100644 --- a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/LemonAutoConfiguration.java +++ b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/LemonAutoConfiguration.java @@ -22,11 +22,9 @@ import com.naturalprogrammer.spring.lemon.commons.security.JwtService; import com.naturalprogrammer.spring.lemon.commons.validation.RetypePasswordValidator; import com.naturalprogrammer.spring.lemon.commonsjpa.LemonCommonsJpaAutoConfiguration; -import com.naturalprogrammer.spring.lemon.commonsweb.security.JwtAuthenticationProvider; import com.naturalprogrammer.spring.lemon.commonsweb.security.LemonWebSecurityConfig; import com.naturalprogrammer.spring.lemon.domain.AbstractUser; import com.naturalprogrammer.spring.lemon.domain.AbstractUserRepository; -import com.naturalprogrammer.spring.lemon.security.JpaJwtAuthenticationProvider; import com.naturalprogrammer.spring.lemon.security.LemonAuthenticationSuccessHandler; import com.naturalprogrammer.spring.lemon.security.LemonJpaSecurityConfig; import com.naturalprogrammer.spring.lemon.security.LemonOAuth2UserService; @@ -113,7 +111,7 @@ public AuthenticationFailureHandler authenticationFailureHandler() { @Bean @ConditionalOnMissingBean(UserDetailsService.class) public , ID extends Serializable> - UserDetailsService userDetailService(AbstractUserRepository userRepository) { + LemonUserDetailsService userDetailService(AbstractUserRepository userRepository) { log.info("Configuring LemonUserDetailsService"); return new LemonUserDetailsService(userRepository); @@ -145,20 +143,6 @@ LemonOAuth2UserService lemonOAuth2UserService( return new LemonOAuth2UserService(userDetailsService, lemonService, passwordEncoder); } - /** - * Configures JwtAuthenticationProvider if missing - */ - @Bean - @ConditionalOnMissingBean(JwtAuthenticationProvider.class) - public , ID extends Serializable> - JwtAuthenticationProvider jwtAuthenticationProvider( - JwtService jwtService, - LemonUserDetailsService userDetailsService) { - - log.info("Configuring JpaJwtAuthenticationProvider"); - return new JpaJwtAuthenticationProvider(jwtService, userDetailsService); - } - /** * Configures LemonSecurityConfig if missing */ diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonJpaSecurityConfig.java b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonJpaSecurityConfig.java index 14348845..cd1c36c1 100644 --- a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonJpaSecurityConfig.java +++ b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonJpaSecurityConfig.java @@ -3,11 +3,10 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.web.builders.HttpSecurity; -import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.web.authentication.AuthenticationFailureHandler; +import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; import com.naturalprogrammer.spring.lemon.commons.LemonProperties; import com.naturalprogrammer.spring.lemon.commonsweb.security.LemonWebSecurityConfig; @@ -24,7 +23,7 @@ public class LemonJpaSecurityConfig extends LemonWebSecurityConfig { private static final Log log = LogFactory.getLog(LemonJpaSecurityConfig.class); private LemonProperties properties; - private UserDetailsService userDetailsService; + private LemonUserDetailsService userDetailsService; private LemonAuthenticationSuccessHandler authenticationSuccessHandler; private AuthenticationFailureHandler authenticationFailureHandler; private LemonOidcUserService oidcUserService; @@ -34,7 +33,7 @@ public class LemonJpaSecurityConfig extends LemonWebSecurityConfig { private PasswordEncoder passwordEncoder; @Autowired - public void createLemonSecurityConfig(LemonProperties properties, UserDetailsService userDetailsService, + public void createLemonSecurityConfig(LemonProperties properties, LemonUserDetailsService userDetailsService, LemonAuthenticationSuccessHandler authenticationSuccessHandler, AuthenticationFailureHandler authenticationFailureHandler, LemonOidcUserService oidcUserService, LemonOAuth2UserService oauth2UserService, @@ -117,13 +116,11 @@ protected void oauth2Client(HttpSecurity http) throws Exception { /** - * Needed for configuring JwtAuthenticationProvider + * Configuring token authentication filter */ - @Override - protected void configure(AuthenticationManagerBuilder auth) throws Exception { - - super.configure(auth); - auth.userDetailsService(userDetailsService) - .passwordEncoder(passwordEncoder); - } + protected void tokenAuthentication(HttpSecurity http) throws Exception { + + http.addFilterBefore(new LemonJpaTokenAuthenticationFilter(jwtService, userDetailsService), + UsernamePasswordAuthenticationFilter.class); + } } diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/JpaJwtAuthenticationProvider.java b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonJpaTokenAuthenticationFilter.java similarity index 62% rename from spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/JpaJwtAuthenticationProvider.java rename to spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonJpaTokenAuthenticationFilter.java index eefc7411..78194427 100644 --- a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/JpaJwtAuthenticationProvider.java +++ b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonJpaTokenAuthenticationFilter.java @@ -8,27 +8,25 @@ import com.naturalprogrammer.spring.lemon.commons.security.JwtService; import com.naturalprogrammer.spring.lemon.commons.security.UserDto; -import com.naturalprogrammer.spring.lemon.commonsweb.security.JwtAuthenticationProvider; +import com.naturalprogrammer.spring.lemon.commonsweb.security.LemonCommonsWebTokenAuthenticationFilter; import com.naturalprogrammer.spring.lemon.domain.AbstractUser; import com.naturalprogrammer.spring.lemon.util.LemonUtils; import com.nimbusds.jwt.JWTClaimsSet; -/** - * Authentication provider for JWT token authentication - */ -public class JpaJwtAuthenticationProvider -, ID extends Serializable> extends JwtAuthenticationProvider { +public class LemonJpaTokenAuthenticationFilter, ID extends Serializable> + extends LemonCommonsWebTokenAuthenticationFilter { - private static final Log log = LogFactory.getLog(JpaJwtAuthenticationProvider.class); + private static final Log log = LogFactory.getLog(LemonJpaTokenAuthenticationFilter.class); - private LemonUserDetailsService userDetailsService; + private LemonUserDetailsService userDetailsService; - public JpaJwtAuthenticationProvider(JwtService jwtService, LemonUserDetailsService userDetailsService) { - + public LemonJpaTokenAuthenticationFilter(JwtService jwtService, + LemonUserDetailsService userDetailsService) { + super(jwtService); this.userDetailsService = userDetailsService; - log.debug("Created"); + log.info("Created"); } @Override From bdad5d67b071e9a748b42f6ba717ffe5fcdef3e7 Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Mon, 1 Oct 2018 22:08:30 +0530 Subject: [PATCH 056/116] Added end-point for full token, etc. --- .../spring/lemon/LemonController.java | 13 +++++++++++ .../spring/lemon/LemonService.java | 22 +++++++++++++++++++ .../spring/lemon/domain/AbstractUser.java | 7 +++++- .../LemonJpaTokenAuthenticationFilter.java | 5 ++++- 4 files changed, 45 insertions(+), 2 deletions(-) diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/LemonController.java b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/LemonController.java index 77c5537d..b2cfc43b 100644 --- a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/LemonController.java +++ b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/LemonController.java @@ -10,12 +10,14 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PatchMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestHeader; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseStatus; @@ -271,6 +273,17 @@ public Map fetchNewToken( } + /** + * Fetch a self-sufficient token with embedded UserDto - for interservice communications + */ + @GetMapping("/fetch-full-token") + public Map fetchFullToken(@RequestHeader(HttpHeaders.AUTHORIZATION) String authHeader) { + + log.debug("Fetching a micro token"); + return lemonService.fetchFullToken(authHeader); + } + + /** * returns the current user and a new authorization token in the response */ diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/LemonService.java b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/LemonService.java index 68f41a80..adb0a473 100644 --- a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/LemonService.java +++ b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/LemonService.java @@ -1,6 +1,7 @@ package com.naturalprogrammer.spring.lemon; import java.io.Serializable; +import java.util.Collections; import java.util.HashMap; import java.util.Map; import java.util.Optional; @@ -747,6 +748,26 @@ protected void hideConfidentialFields(U user) { } + @PreAuthorize("isAuthenticated()") + public Map fetchFullToken(String authHeader) { + + LecUtils.ensureCredentials(jwtService.parseClaim(authHeader.substring(LecUtils.TOKEN_PREFIX_LENGTH), + JwtService.USER_CLAIM) == null, "com.naturalprogrammer.spring.fullTokenNotAllowed"); + + UserDto currentUser = LecwUtils.currentUser(); + + Map claimMap = Collections.singletonMap(JwtService.USER_CLAIM, + LecUtils.serialize(currentUser)); // Not serializing converts it to a JsonNode + + Map tokenMap = Collections.singletonMap("token", LecUtils.TOKEN_PREFIX + + jwtService.createToken(JwtService.AUTH_AUDIENCE, currentUser.getUsername(), + Long.valueOf(properties.getJwt().getShortLivedMillis()), + claimMap)); + + return tokenMap; + } + + /** * Adds a Lemon-Authorization header to the response */ @@ -757,6 +778,7 @@ public void addAuthHeader(HttpServletResponse response, String username, Long ex jwtService.createToken(JwtService.AUTH_AUDIENCE, username, expirationMillis)); } + public Optional findUserById(String id) { return userRepository.findById(toId(id)); } diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/domain/AbstractUser.java b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/domain/AbstractUser.java index 3dce1604..8aaa80f8 100644 --- a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/domain/AbstractUser.java +++ b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/domain/AbstractUser.java @@ -104,7 +104,12 @@ public UserDto toUserDto() { userDto.setId(getId().toString()); userDto.setUsername(email); userDto.setPassword(password); - userDto.setRoles(roles); + + // roles would be org.hibernate.collection.internal.PersistentSet, + // which is not in another microservices not having Hibernate. + // So, let's convert it to HashSet + userDto.setRoles(new HashSet(roles)); + userDto.setTag(toTag()); userDto.initialize(); diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonJpaTokenAuthenticationFilter.java b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonJpaTokenAuthenticationFilter.java index 78194427..4c09b4e5 100644 --- a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonJpaTokenAuthenticationFilter.java +++ b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonJpaTokenAuthenticationFilter.java @@ -39,6 +39,9 @@ protected UserDto fetchUserDto(JWTClaimsSet claims) { log.debug("User found ..."); LemonUtils.ensureCredentialsUpToDate(claims, user); - return user.toUserDto(); + UserDto userDto = user.toUserDto(); + userDto.setPassword(null); + + return userDto; } } From 9e4122d28bb61ecab58f11042e91e084ac39f490 Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Tue, 2 Oct 2018 11:34:28 +0530 Subject: [PATCH 057/116] Added test case for not returning password to front-end --- .../com/naturalprogrammer/spring/lemondemo/BasicMvcTests.java | 3 ++- .../com/naturalprogrammer/spring/lemondemo/BasicTests.java | 4 +++- .../spring/lemon/commonsjpa/LemonEntity.java | 2 +- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/BasicMvcTests.java b/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/BasicMvcTests.java index fec54da0..42c8d86a 100644 --- a/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/BasicMvcTests.java +++ b/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/BasicMvcTests.java @@ -31,7 +31,8 @@ public void testGetContextLoggedIn() throws Exception { .andExpect(header().string(LecUtils.TOKEN_RESPONSE_HEADER_NAME, containsString("."))) .andExpect(jsonPath("$.context.reCaptchaSiteKey").isString()) .andExpect(jsonPath("$.user.id").value(ADMIN_ID)) - .andExpect(jsonPath("$.user.roles[0]").value("ADMIN")); + .andExpect(jsonPath("$.user.roles[0]").value("ADMIN")) + .andExpect(jsonPath("$.user.password").doesNotExist()); } @Test diff --git a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/BasicTests.java b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/BasicTests.java index e4b93a24..ef1e0981 100644 --- a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/BasicTests.java +++ b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/BasicTests.java @@ -4,6 +4,7 @@ import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.CLIENT; import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.TOKENS; import static com.naturalprogrammer.spring.lemondemo.controllers.MyController.BASE_URI; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; import org.junit.Test; @@ -29,7 +30,8 @@ public void testGetContextLoggedIn() throws Exception { .expectBody() .jsonPath("$.context.reCaptchaSiteKey").exists() .jsonPath("$.user.id").isEqualTo(ADMIN_ID.toString()) - .jsonPath("$.user.roles[0]").isEqualTo("ADMIN"); + .jsonPath("$.user.roles[0]").isEqualTo("ADMIN") + .jsonPath("$.user.password").doesNotExist(); } @Test diff --git a/spring-lemon-commons-jpa/src/main/java/com/naturalprogrammer/spring/lemon/commonsjpa/LemonEntity.java b/spring-lemon-commons-jpa/src/main/java/com/naturalprogrammer/spring/lemon/commonsjpa/LemonEntity.java index 37ac4f45..71fd9443 100644 --- a/spring-lemon-commons-jpa/src/main/java/com/naturalprogrammer/spring/lemon/commonsjpa/LemonEntity.java +++ b/spring-lemon-commons-jpa/src/main/java/com/naturalprogrammer/spring/lemon/commonsjpa/LemonEntity.java @@ -28,7 +28,7 @@ */ @MappedSuperclass @Getter @Setter -@JsonIgnoreProperties({ "createdBy", "lastModifiedBy", "createdDate", "lastModifiedDate" }) +@JsonIgnoreProperties({ "createdById", "lastModifiedById", "createdDate", "lastModifiedDate", "new" }) public class LemonEntity extends AbstractPersistable implements PermissionEvaluatorEntity { private static final long serialVersionUID = -8151190931948396443L; From bcdbee1a000c3589521980982ce9d14a6e1e1228 Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Sat, 13 Oct 2018 14:31:56 +0530 Subject: [PATCH 058/116] Updated README --- README.md | 38 ++++++++++++++++++++++++++++++-------- 1 file changed, 30 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index fc06ced8..22f812a6 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,8 @@ When developing **real-world** Spring REST APIs and microservices, you face many 1. How to handle _validations_ and _exceptions_ in a cross functional manner and send precise errors to the client. 1. How exactly to support multiple _social sign up/in_, using _OpenID Connect_ or _OAuth2_ providers such as _Google_ and _Facebook_. 1. How to code a robust user module (with features like _sign up_, _sign in_, _verify email_, _social sign up/in_, _update profile_, _forgot password_, _change password_, _change email_, _token authentication_ etc.) and share it across all your applications. -1. _What would be good ways to test your API_. +1. How to _secure microservices_ effeciently, using long-lived and short-lived JWTs. +1. What would be good ways to _test your API_. 1. How to do _Captcha validation_. 1. How to properly organize _application properties_. 1. How to use _PATCH_ and _JsonPatch_ to handle partial updates correctly. @@ -17,13 +18,31 @@ When developing **real-world** Spring REST APIs and microservices, you face many Coding all this rightly needs in-depth knowledge of Spring. It also takes a lot of development time and effort, and needs to be properly maintained as new versions of Spring modules come out. -**Spring Lemon** relieves you of all this burden. It's a tiny open source library holding all these common configuration and components, and also a production grade user module with all the abovementioned features. +**Spring Lemon** relieves you of all this burden. It's a set of configurable and extensible libraries, providing all above features. Use these to develop quality reactive or non-reactive monolith or microservices applications easily. -Even if you don't plan to use Spring Lemon, it's a good example application to learn from, because it showcases the essential best practices for developing elegant web services and microservices using Spring. +Even if you don't plan to use Spring Lemon, it's a good example to learn from, because it showcases the essential best practices for developing elegant web services and microservices using Spring. Most Spring Boot applications can use Spring Lemon straight away, with some simple configurations. But, if you don't find it suitable for your application, feel free to fork it, or just roll out your own library by learning its patterns and practices. Better yet, be a contributor! -Watch [this video tutorial](https://www.naturalprogrammer.com/p/spring-lemon-restful-web-services-development) or read [this quick starter guide](https://github.com/naturalprogrammer/spring-lemon/wiki/Getting-Started-With-Spring-Lemon) for getting started. +Read [this quick starter guide](https://github.com/naturalprogrammer/spring-lemon/wiki/Getting-Started-With-Spring-Lemon) or watch [this video tutorial](https://www.naturalprogrammer.com/p/spring-lemon-restful-web-services-development) for getting started. + +## Libraries hierarchy + +* **spring-lemon-exceptions**: Useful for elegant exception handling and validation in any Spring project + * **spring-lemon-commons**: Common for all things below + * **spring-lemon-commons-web**: For developing Spring Web (non-reactive) microservices + * **spring-lemon-commons-jpa**: For developing Spring Web (non-reactive) JPA microservices + * **spring-lemon-jpa**: For developing Spring Web (non-reactive) JPA monolith or auth-microservice + * **spring-lemon-commons-reactive**: For developing Spring WebFlux (reactive) microservices + * **spring-lemon-commons-mongo**: For developing Spring WebFlux (reactive) MongoDB microservices + * **spring-lemon-rective**: For developing Spring WebFlux (reactive) MongoDB monolith or auth-microservice + +For example usage, see + +* [Demo non-reactive monolith](https://github.com/naturalprogrammer/spring-lemon/tree/master/lemon-demo-jpa) +* [Demo reactive monolith](https://github.com/naturalprogrammer/spring-lemon/tree/master/lemon-demo-reactive) +* [Demo non-reactive microservices](https://github.com/naturalprogrammer/np-microservices-sample-01) and its [configuration repository](https://github.com/naturalprogrammer/np-microservices-sample-01-config) +* [Demo reactive microservices](https://github.com/naturalprogrammer/np-microservices-sample-02) and its [configuration repository](https://github.com/naturalprogrammer/np-microservices-sample-02-config) ## Documentation and Resources @@ -33,10 +52,13 @@ Watch [this video tutorial](https://www.naturalprogrammer.com/p/spring-lemon-res 1. _Getting started guide_ 1. [Book](https://github.com/naturalprogrammer/spring-lemon/wiki/Getting-Started-With-Spring-Lemon) 1. [Video Tutorial](https://www.naturalprogrammer.com/p/spring-lemon-restful-web-services-development) -1. _Example applications_ — [Non-reactive](https://github.com/naturalprogrammer/spring-lemon/tree/master/lemon-demo-jpa) and [reactive](https://github.com/naturalprogrammer/spring-lemon/tree/master/lemon-demo-reactive) sample applications using Spring Lemon. Quite similar to the one developed in the above [getting started guide](https://github.com/naturalprogrammer/spring-lemon/wiki/Getting-Started-With-Spring-Lemon), but additionally have automated tests. -1. _[API documentation](https://documenter.getpostman.com/view/305915/RVu2mqEH)_ of the above application. -1. _[Example AngularJS front-end application](https://github.com/naturalprogrammer/spring-lemon/tree/master/lemon-demo-angularjs)_ — A sample AngularJS 1.x front-end. It'll work both for the application developed in the above [getting started guide](https://github.com/naturalprogrammer/spring-lemon/wiki/Getting-Started-With-Spring-Lemon) as well as the [Lemon Demo application](https://github.com/naturalprogrammer/spring-lemon/tree/master/lemon-demo-jpa). See the [Getting Started Guide](https://github.com/naturalprogrammer/spring-lemon/wiki/Getting-Started-With-Spring-Lemon) on how to use it. -1. _[Example reactive microservices](https://github.com/naturalprogrammer/np-microservices-sample-02) using Spring Lemon, and its [configuration repo](https://github.com/naturalprogrammer/np-microservices-sample-02-config)_ — A sample reactive microservices application depicting how easy it is to develop reactive microservices using Spring Lemon. +1. _Example applications_ + * [Demo non-reactive monolith](https://github.com/naturalprogrammer/spring-lemon/tree/master/lemon-demo-jpa) + * [Demo reactive monolith](https://github.com/naturalprogrammer/spring-lemon/tree/master/lemon-demo-reactive) + * [Demo non-reactive microservices](https://github.com/naturalprogrammer/np-microservices-sample-01) and its [configuration repository](https://github.com/naturalprogrammer/np-microservices-sample-01-config) + * [Demo reactive microservices](https://github.com/naturalprogrammer/np-microservices-sample-02) and its [configuration repository](https://github.com/naturalprogrammer/np-microservices-sample-02-config) +1. _[API documentation](https://documenter.getpostman.com/view/305915/RVu2mqEH)_ of the above applications. +1. _[Example AngularJS front-end application](https://github.com/naturalprogrammer/spring-lemon/tree/master/lemon-demo-angularjs)_ — A sample AngularJS 1.x front-end. It'll work for the application developed in the above [getting started guide](https://github.com/naturalprogrammer/spring-lemon/wiki/Getting-Started-With-Spring-Lemon) as well all the above example applications. See the [Getting Started Guide](https://github.com/naturalprogrammer/spring-lemon/wiki/Getting-Started-With-Spring-Lemon) on how to use it. 1. _[Spring Framework Recipes For Real World Application Development](https://www.naturalprogrammer.com/p/spring-framework-book-of-best-practices)_ — a live book discussing key real-world topics on developing Spring applications, APIs and microservoces. Includes many Spring Lemon topics. [Click here](https://www.naturalprogrammer.com/p/spring-framework-book-of-best-practices) to get it now for FREE! 1. Video tutorials coming soon: 1. Spring Framework 5 REST API Development — A Complete Blueprint For Real-World Developers From a754764864f43e0743c4cc0bba583e9e9894115f Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Sat, 13 Oct 2018 19:40:59 +0530 Subject: [PATCH 059/116] Updated README --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 22f812a6..c425d215 100644 --- a/README.md +++ b/README.md @@ -60,6 +60,8 @@ For example usage, see 1. _[API documentation](https://documenter.getpostman.com/view/305915/RVu2mqEH)_ of the above applications. 1. _[Example AngularJS front-end application](https://github.com/naturalprogrammer/spring-lemon/tree/master/lemon-demo-angularjs)_ — A sample AngularJS 1.x front-end. It'll work for the application developed in the above [getting started guide](https://github.com/naturalprogrammer/spring-lemon/wiki/Getting-Started-With-Spring-Lemon) as well all the above example applications. See the [Getting Started Guide](https://github.com/naturalprogrammer/spring-lemon/wiki/Getting-Started-With-Spring-Lemon) on how to use it. 1. _[Spring Framework Recipes For Real World Application Development](https://www.naturalprogrammer.com/p/spring-framework-book-of-best-practices)_ — a live book discussing key real-world topics on developing Spring applications, APIs and microservoces. Includes many Spring Lemon topics. [Click here](https://www.naturalprogrammer.com/p/spring-framework-book-of-best-practices) to get it now for FREE! +1. [Using Spring Lemon Effectively](https://github.com/naturalprogrammer/spring-lemon/wiki/Using-Spring-Lemon-Effectively) +1. [DZone Articles](https://dzone.com/users/1211183/skpatel20.html) 1. Video tutorials coming soon: 1. Spring Framework 5 REST API Development — A Complete Blueprint For Real-World Developers 1. Spring WebFlux Reactive REST API Development — A Complete Blueprint For Real-World Developers From beec6568537d3011a586fe80697078a228ea3ec1 Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Sat, 13 Oct 2018 19:58:53 +0530 Subject: [PATCH 060/116] Moving towards 1.0.0.M8 --- lemon-demo-jpa/pom.xml | 2 +- lemon-demo-reactive/pom.xml | 2 +- pom.xml | 2 +- spring-lemon-commons-jpa/pom.xml | 2 +- spring-lemon-commons-mongo/pom.xml | 2 +- spring-lemon-commons-reactive/pom.xml | 2 +- spring-lemon-commons-web/pom.xml | 2 +- spring-lemon-commons/pom.xml | 2 +- spring-lemon-exceptions/pom.xml | 2 +- .../lemon/exceptions/util/LexUtils.java | 20 ------------------- spring-lemon-jpa/pom.xml | 2 +- spring-lemon-reactive/pom.xml | 2 +- 12 files changed, 11 insertions(+), 31 deletions(-) diff --git a/lemon-demo-jpa/pom.xml b/lemon-demo-jpa/pom.xml index 14a2d344..7a337c0b 100644 --- a/lemon-demo-jpa/pom.xml +++ b/lemon-demo-jpa/pom.xml @@ -14,7 +14,7 @@ com.naturalprogrammer spring-lemon - 1.0.0.M7 + 1.0.0.M8 diff --git a/lemon-demo-reactive/pom.xml b/lemon-demo-reactive/pom.xml index 9ecd26cf..a18a44f0 100644 --- a/lemon-demo-reactive/pom.xml +++ b/lemon-demo-reactive/pom.xml @@ -13,7 +13,7 @@ com.naturalprogrammer spring-lemon - 1.0.0.M7 + 1.0.0.M8 diff --git a/pom.xml b/pom.xml index e16ecf2b..e221118d 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.naturalprogrammer spring-lemon - 1.0.0.M7 + 1.0.0.M8 pom spring-lemon diff --git a/spring-lemon-commons-jpa/pom.xml b/spring-lemon-commons-jpa/pom.xml index 26e35cc2..9a009e94 100644 --- a/spring-lemon-commons-jpa/pom.xml +++ b/spring-lemon-commons-jpa/pom.xml @@ -13,7 +13,7 @@ com.naturalprogrammer spring-lemon - 1.0.0.M7 + 1.0.0.M8 diff --git a/spring-lemon-commons-mongo/pom.xml b/spring-lemon-commons-mongo/pom.xml index 01b9f1aa..3c72890c 100644 --- a/spring-lemon-commons-mongo/pom.xml +++ b/spring-lemon-commons-mongo/pom.xml @@ -13,7 +13,7 @@ com.naturalprogrammer spring-lemon - 1.0.0.M7 + 1.0.0.M8 diff --git a/spring-lemon-commons-reactive/pom.xml b/spring-lemon-commons-reactive/pom.xml index 8ade1524..f4771652 100644 --- a/spring-lemon-commons-reactive/pom.xml +++ b/spring-lemon-commons-reactive/pom.xml @@ -13,7 +13,7 @@ com.naturalprogrammer spring-lemon - 1.0.0.M7 + 1.0.0.M8 diff --git a/spring-lemon-commons-web/pom.xml b/spring-lemon-commons-web/pom.xml index 53e9d10a..ef30de83 100644 --- a/spring-lemon-commons-web/pom.xml +++ b/spring-lemon-commons-web/pom.xml @@ -13,7 +13,7 @@ com.naturalprogrammer spring-lemon - 1.0.0.M7 + 1.0.0.M8 diff --git a/spring-lemon-commons/pom.xml b/spring-lemon-commons/pom.xml index 636df9bf..85d16092 100644 --- a/spring-lemon-commons/pom.xml +++ b/spring-lemon-commons/pom.xml @@ -14,7 +14,7 @@ com.naturalprogrammer spring-lemon - 1.0.0.M7 + 1.0.0.M8 diff --git a/spring-lemon-exceptions/pom.xml b/spring-lemon-exceptions/pom.xml index 5c739a62..698bdac7 100644 --- a/spring-lemon-exceptions/pom.xml +++ b/spring-lemon-exceptions/pom.xml @@ -13,7 +13,7 @@ com.naturalprogrammer spring-lemon - 1.0.0.M7 + 1.0.0.M8 diff --git a/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/util/LexUtils.java b/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/util/LexUtils.java index 400fa6c8..403ca3f9 100644 --- a/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/util/LexUtils.java +++ b/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/util/LexUtils.java @@ -31,8 +31,6 @@ public class LexUtils { /** * Constructor - * - * @param messageSource */ public LexUtils(MessageSource messageSource, LocalValidatorFactoryBean validator) { @@ -56,9 +54,6 @@ public void postConstruct() { /** * Gets a message from messages.properties - * - * @param messageKey the key of the message - * @param args any arguments */ public static String getMessage(String messageKey, Object... args) { @@ -73,10 +68,6 @@ public static String getMessage(String messageKey, Object... args) { /** * Creates a MultiErrorException out of the given parameters - * - * @param valid the condition to check for - * @param messageKey key of the error message - * @param args any message arguments */ public static void validate(String name, T object, Class... groups) { @@ -89,10 +80,6 @@ public static void validate(String name, T object, Class... groups) { /** * Creates a MultiErrorException out of the given parameters - * - * @param valid the condition to check for - * @param messageKey key of the error message - * @param args any message arguments */ public static MultiErrorException validate( boolean valid, String messageKey, Object... args) { @@ -103,11 +90,6 @@ public static MultiErrorException validate( /** * Creates a MultiErrorException out of the given parameters - * - * @param fieldName the name of the field related to the error - * @param valid the condition to check for - * @param messageKey key of the error message - * @param args any message arguments */ public static MultiErrorException validate( String fieldName, boolean valid, String messageKey, Object... args) { @@ -118,8 +100,6 @@ public static MultiErrorException validate( /** * Throws 404 Error is the entity isn't found - * - * @param entity */ public static void ensureFound(T entity) { diff --git a/spring-lemon-jpa/pom.xml b/spring-lemon-jpa/pom.xml index 7657b0e9..72615faa 100644 --- a/spring-lemon-jpa/pom.xml +++ b/spring-lemon-jpa/pom.xml @@ -13,7 +13,7 @@ com.naturalprogrammer spring-lemon - 1.0.0.M7 + 1.0.0.M8 diff --git a/spring-lemon-reactive/pom.xml b/spring-lemon-reactive/pom.xml index f3eeb2ae..eab6f878 100644 --- a/spring-lemon-reactive/pom.xml +++ b/spring-lemon-reactive/pom.xml @@ -13,7 +13,7 @@ com.naturalprogrammer spring-lemon - 1.0.0.M7 + 1.0.0.M8 From f55db64f8a7856ae81a4092292197cce554080cf Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Sat, 20 Oct 2018 13:16:19 +0530 Subject: [PATCH 061/116] Changed the exception handler map key to class --- .../exceptions/handlers/VersionExceptionHandler.java | 2 +- .../DefaultExceptionHandlerControllerAdvice.java | 3 ++- .../handlers/AccessDeniedExceptionHandler.java | 2 +- .../handlers/BadCredentialsExceptionHandler.java | 2 +- .../exceptions/handlers/JsonParseExceptionHandler.java | 2 +- .../exceptions/handlers/JsonPatchExceptionHandler.java | 2 +- .../handlers/JsonProcessingExceptionHandler.java | 2 +- .../handlers/UsernameNotFoundExceptionHandler.java | 2 +- .../spring/lemon/exceptions/ErrorResponseComposer.java | 6 +++--- .../handlers/AbstractBadRequestExceptionHandler.java | 4 ++-- .../exceptions/handlers/AbstractExceptionHandler.java | 10 +++++----- .../handlers/ConstraintViolationExceptionHandler.java | 6 +++--- .../ExplicitConstraintViolationExceptionHandler.java | 2 +- .../handlers/MultiErrorExceptionHandler.java | 2 +- .../handlers/WebExchangeBindExceptionHandler.java | 2 +- 15 files changed, 25 insertions(+), 24 deletions(-) diff --git a/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/exceptions/handlers/VersionExceptionHandler.java b/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/exceptions/handlers/VersionExceptionHandler.java index 1db80d48..ae68d798 100644 --- a/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/exceptions/handlers/VersionExceptionHandler.java +++ b/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/exceptions/handlers/VersionExceptionHandler.java @@ -14,7 +14,7 @@ public class VersionExceptionHandler extends AbstractExceptionHandler handleException(T ex) throws T { log.warn("Handling exception", ex); - // We didn't do this inside compose because LemonErrorAttributes would do it differently + // We didn't do this inside compose because LemonErrorAttributes + // and LemonReactiveErrorAttributes would do it differently errorResponse.setException(LexUtils.getRootExceptionName(ex)); return new ResponseEntity(errorResponse, HttpStatus.valueOf(errorResponse.getStatus())); diff --git a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/exceptions/handlers/AccessDeniedExceptionHandler.java b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/exceptions/handlers/AccessDeniedExceptionHandler.java index b283a7ef..ec896966 100644 --- a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/exceptions/handlers/AccessDeniedExceptionHandler.java +++ b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/exceptions/handlers/AccessDeniedExceptionHandler.java @@ -14,7 +14,7 @@ public class AccessDeniedExceptionHandler extends AbstractExceptionHandler { private static final Log log = LogFactory.getLog(ErrorResponseComposer.class); - private final Map> handlers; + private final Map, AbstractExceptionHandler> handlers; public ErrorResponseComposer(List> handlers) { this.handlers = handlers.stream().collect( - Collectors.toMap(AbstractExceptionHandler::getExceptionName, + Collectors.toMap(AbstractExceptionHandler::getExceptionClass, Function.identity(), (handler1, handler2) -> { return AnnotationAwareOrderComparator @@ -49,7 +49,7 @@ public Optional compose(T ex) { while (ex != null) { - handler = handlers.get(ex.getClass().getSimpleName()); + handler = handlers.get(ex.getClass()); if (handler != null) // found a handler break; diff --git a/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/handlers/AbstractBadRequestExceptionHandler.java b/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/handlers/AbstractBadRequestExceptionHandler.java index 974c400a..8ddede77 100644 --- a/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/handlers/AbstractBadRequestExceptionHandler.java +++ b/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/handlers/AbstractBadRequestExceptionHandler.java @@ -10,8 +10,8 @@ @Order(Ordered.LOWEST_PRECEDENCE) public abstract class AbstractBadRequestExceptionHandler extends AbstractExceptionHandler { - public AbstractBadRequestExceptionHandler(String exceptionName) { - super(exceptionName); + public AbstractBadRequestExceptionHandler(Class exceptionClass) { + super(exceptionClass); } @Override diff --git a/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/handlers/AbstractExceptionHandler.java b/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/handlers/AbstractExceptionHandler.java index ca79ba79..4548f066 100644 --- a/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/handlers/AbstractExceptionHandler.java +++ b/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/handlers/AbstractExceptionHandler.java @@ -16,14 +16,14 @@ public abstract class AbstractExceptionHandler { protected final Log log = LogFactory.getLog(this.getClass()); - private String exceptionName; + private Class exceptionClass; - public AbstractExceptionHandler(String exceptionName) { - this.exceptionName = exceptionName; + public AbstractExceptionHandler(Class exceptionClass) { + this.exceptionClass = exceptionClass; } - public String getExceptionName() { - return exceptionName; + public Class getExceptionClass() { + return exceptionClass; } protected String getMessage(T ex) { diff --git a/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/handlers/ConstraintViolationExceptionHandler.java b/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/handlers/ConstraintViolationExceptionHandler.java index d35fa72d..5e0e1c1f 100644 --- a/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/handlers/ConstraintViolationExceptionHandler.java +++ b/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/handlers/ConstraintViolationExceptionHandler.java @@ -18,12 +18,12 @@ public class ConstraintViolationExceptionHandler exceptionClass) { + super(exceptionClass); } @Override diff --git a/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/handlers/ExplicitConstraintViolationExceptionHandler.java b/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/handlers/ExplicitConstraintViolationExceptionHandler.java index 935f0756..b257d567 100644 --- a/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/handlers/ExplicitConstraintViolationExceptionHandler.java +++ b/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/handlers/ExplicitConstraintViolationExceptionHandler.java @@ -16,7 +16,7 @@ public class ExplicitConstraintViolationExceptionHandler public ExplicitConstraintViolationExceptionHandler() { - super(ExplicitConstraintViolationException.class.getSimpleName()); + super(ExplicitConstraintViolationException.class); log.info("Created"); } diff --git a/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/handlers/MultiErrorExceptionHandler.java b/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/handlers/MultiErrorExceptionHandler.java index 5583b114..82e0925a 100644 --- a/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/handlers/MultiErrorExceptionHandler.java +++ b/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/handlers/MultiErrorExceptionHandler.java @@ -16,7 +16,7 @@ public class MultiErrorExceptionHandler extends AbstractExceptionHandler Date: Sat, 20 Oct 2018 13:41:18 +0530 Subject: [PATCH 062/116] Coded ExceptionCodeMaker --- .../LemonCommonsReactiveAutoConfiguration.java | 7 +++++-- .../exceptions/LemonReactiveErrorAttributes.java | 9 +++++++-- .../LemonCommonsWebAutoConfiguration.java | 13 +++++++++---- .../DefaultExceptionHandlerControllerAdvice.java | 9 +++++++-- .../commonsweb/exceptions/LemonErrorAttributes.java | 9 +++++++-- .../spring/lemon/exceptions/ExceptionCodeMaker.java | 7 +++++++ .../LemonExceptionsAutoConfiguration.java | 12 ++++++++++++ .../spring/lemon/exceptions/util/LexUtils.java | 7 +++---- 8 files changed, 57 insertions(+), 16 deletions(-) create mode 100644 spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/ExceptionCodeMaker.java diff --git a/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/LemonCommonsReactiveAutoConfiguration.java b/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/LemonCommonsReactiveAutoConfiguration.java index 507cdf11..f68deb30 100644 --- a/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/LemonCommonsReactiveAutoConfiguration.java +++ b/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/LemonCommonsReactiveAutoConfiguration.java @@ -34,6 +34,7 @@ import com.naturalprogrammer.spring.lemon.commonsreactive.security.LemonReactiveCorsConfig; import com.naturalprogrammer.spring.lemon.commonsreactive.util.LecrUtils; import com.naturalprogrammer.spring.lemon.exceptions.ErrorResponseComposer; +import com.naturalprogrammer.spring.lemon.exceptions.ExceptionCodeMaker; import com.naturalprogrammer.spring.lemon.exceptions.util.LexUtils; @Configuration @@ -59,10 +60,12 @@ public LemonCommonsReactiveAutoConfiguration() { @Bean @ConditionalOnMissingBean(ErrorAttributes.class) public - ErrorAttributes errorAttributes(ErrorResponseComposer errorResponseComposer) { + ErrorAttributes errorAttributes( + ErrorResponseComposer errorResponseComposer, + ExceptionCodeMaker exceptionCodeMaker) { log.info("Configuring LemonErrorAttributes"); - return new LemonReactiveErrorAttributes(errorResponseComposer); + return new LemonReactiveErrorAttributes(errorResponseComposer, exceptionCodeMaker); } diff --git a/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/exceptions/LemonReactiveErrorAttributes.java b/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/exceptions/LemonReactiveErrorAttributes.java index 5e5850a1..607470c8 100644 --- a/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/exceptions/LemonReactiveErrorAttributes.java +++ b/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/exceptions/LemonReactiveErrorAttributes.java @@ -8,6 +8,7 @@ import org.springframework.web.reactive.function.server.ServerRequest; import com.naturalprogrammer.spring.lemon.exceptions.ErrorResponseComposer; +import com.naturalprogrammer.spring.lemon.exceptions.ExceptionCodeMaker; import com.naturalprogrammer.spring.lemon.exceptions.util.LexUtils; public class LemonReactiveErrorAttributes extends DefaultErrorAttributes { @@ -18,10 +19,14 @@ public class LemonReactiveErrorAttributes extends DefaultEr * Component that actually builds the error response */ private ErrorResponseComposer errorResponseComposer; + private ExceptionCodeMaker exceptionCodeMaker; - public LemonReactiveErrorAttributes(ErrorResponseComposer errorResponseComposer) { + public LemonReactiveErrorAttributes( + ErrorResponseComposer errorResponseComposer, + ExceptionCodeMaker exceptionCodeMaker) { this.errorResponseComposer = errorResponseComposer; + this.exceptionCodeMaker = exceptionCodeMaker; log.info("Created"); } @@ -43,7 +48,7 @@ protected void addLemonErrorDetails( Throwable ex = getError(request); - errorAttributes.put("exception", LexUtils.getRootExceptionName(ex)); + errorAttributes.put("exception", exceptionCodeMaker.make(LexUtils.getRootException(ex))); errorResponseComposer.compose((T)ex).ifPresent(errorResponse -> { diff --git a/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/LemonCommonsWebAutoConfiguration.java b/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/LemonCommonsWebAutoConfiguration.java index 7d6615b5..c8bf926e 100644 --- a/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/LemonCommonsWebAutoConfiguration.java +++ b/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/LemonCommonsWebAutoConfiguration.java @@ -35,6 +35,7 @@ import com.naturalprogrammer.spring.lemon.commonsweb.security.LemonWebSecurityConfig; import com.naturalprogrammer.spring.lemon.commonsweb.util.LecwUtils; import com.naturalprogrammer.spring.lemon.exceptions.ErrorResponseComposer; +import com.naturalprogrammer.spring.lemon.exceptions.ExceptionCodeMaker; @Configuration @EnableSpringDataWebSupport @@ -85,10 +86,12 @@ public MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter( @Bean @ConditionalOnMissingBean(DefaultExceptionHandlerControllerAdvice.class) public - DefaultExceptionHandlerControllerAdvice defaultExceptionHandlerControllerAdvice(ErrorResponseComposer errorResponseComposer) { + DefaultExceptionHandlerControllerAdvice defaultExceptionHandlerControllerAdvice( + ErrorResponseComposer errorResponseComposer, + ExceptionCodeMaker exceptionCodeMaker) { log.info("Configuring DefaultExceptionHandlerControllerAdvice"); - return new DefaultExceptionHandlerControllerAdvice(errorResponseComposer); + return new DefaultExceptionHandlerControllerAdvice(errorResponseComposer, exceptionCodeMaker); } /** @@ -97,10 +100,12 @@ DefaultExceptionHandlerControllerAdvice defaultExceptionHandlerControllerAdvi @Bean @ConditionalOnMissingBean(ErrorAttributes.class) public - ErrorAttributes errorAttributes(ErrorResponseComposer errorResponseComposer) { + ErrorAttributes errorAttributes( + ErrorResponseComposer errorResponseComposer, + ExceptionCodeMaker exceptionCodeMaker) { log.info("Configuring LemonErrorAttributes"); - return new LemonErrorAttributes(errorResponseComposer); + return new LemonErrorAttributes(errorResponseComposer, exceptionCodeMaker); } /** diff --git a/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/exceptions/DefaultExceptionHandlerControllerAdvice.java b/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/exceptions/DefaultExceptionHandlerControllerAdvice.java index 4edad2bf..fbcd85bc 100644 --- a/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/exceptions/DefaultExceptionHandlerControllerAdvice.java +++ b/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/exceptions/DefaultExceptionHandlerControllerAdvice.java @@ -10,6 +10,7 @@ import com.naturalprogrammer.spring.lemon.exceptions.ErrorResponse; import com.naturalprogrammer.spring.lemon.exceptions.ErrorResponseComposer; +import com.naturalprogrammer.spring.lemon.exceptions.ExceptionCodeMaker; import com.naturalprogrammer.spring.lemon.exceptions.util.LexUtils; /** @@ -24,10 +25,14 @@ public class DefaultExceptionHandlerControllerAdvice { * Component that actually builds the error response */ private ErrorResponseComposer errorResponseComposer; + private ExceptionCodeMaker exceptionCodeMaker; - public DefaultExceptionHandlerControllerAdvice(ErrorResponseComposer errorResponseComposer) { + public DefaultExceptionHandlerControllerAdvice( + ErrorResponseComposer errorResponseComposer, + ExceptionCodeMaker exceptionCodeMaker) { this.errorResponseComposer = errorResponseComposer; + this.exceptionCodeMaker = exceptionCodeMaker; log.info("Created"); } @@ -49,7 +54,7 @@ public ResponseEntity handleException(T ex) throws T { // We didn't do this inside compose because LemonErrorAttributes // and LemonReactiveErrorAttributes would do it differently - errorResponse.setException(LexUtils.getRootExceptionName(ex)); + errorResponse.setException(exceptionCodeMaker.make(LexUtils.getRootException(ex))); return new ResponseEntity(errorResponse, HttpStatus.valueOf(errorResponse.getStatus())); } diff --git a/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/exceptions/LemonErrorAttributes.java b/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/exceptions/LemonErrorAttributes.java index c27cd5c7..f8a5265c 100644 --- a/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/exceptions/LemonErrorAttributes.java +++ b/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/exceptions/LemonErrorAttributes.java @@ -8,6 +8,7 @@ import org.springframework.web.context.request.WebRequest; import com.naturalprogrammer.spring.lemon.exceptions.ErrorResponseComposer; +import com.naturalprogrammer.spring.lemon.exceptions.ExceptionCodeMaker; import com.naturalprogrammer.spring.lemon.exceptions.util.LexUtils; /** @@ -22,10 +23,14 @@ public class LemonErrorAttributes extends DefaultErrorAttri static final String HTTP_STATUS_KEY = "httpStatus"; private ErrorResponseComposer errorResponseComposer; + private ExceptionCodeMaker exceptionCodeMaker; - public LemonErrorAttributes(ErrorResponseComposer errorResponseComposer) { + public LemonErrorAttributes( + ErrorResponseComposer errorResponseComposer, + ExceptionCodeMaker exceptionCodeMaker) { this.errorResponseComposer = errorResponseComposer; + this.exceptionCodeMaker = exceptionCodeMaker; log.info("Created"); } @@ -53,7 +58,7 @@ protected void addLemonErrorDetails( Throwable ex = getError(request); - errorAttributes.put("exception", LexUtils.getRootExceptionName(ex)); + errorAttributes.put("exception", exceptionCodeMaker.make(LexUtils.getRootException(ex))); errorResponseComposer.compose((T)ex).ifPresent(errorResponse -> { diff --git a/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/ExceptionCodeMaker.java b/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/ExceptionCodeMaker.java new file mode 100644 index 00000000..8b1daffa --- /dev/null +++ b/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/ExceptionCodeMaker.java @@ -0,0 +1,7 @@ +package com.naturalprogrammer.spring.lemon.exceptions; + +@FunctionalInterface +public interface ExceptionCodeMaker { + + String make(Throwable t); +} diff --git a/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/LemonExceptionsAutoConfiguration.java b/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/LemonExceptionsAutoConfiguration.java index 5e8425a0..58976699 100644 --- a/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/LemonExceptionsAutoConfiguration.java +++ b/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/LemonExceptionsAutoConfiguration.java @@ -41,8 +41,20 @@ ErrorResponseComposer errorResponseComposer(List> log.info("Configuring ErrorResponseComposer"); return new ErrorResponseComposer(handlers); } + + /** + * Configures ExceptionCodeMaker if missing + */ + @Bean + @ConditionalOnMissingBean(ExceptionCodeMaker.class) + public ExceptionCodeMaker exceptionCodeMaker() { + + log.info("Configuring ExceptionCodeMaker"); + return ex -> ex.getClass().getSimpleName(); + } + /** * Configures LemonUtils */ diff --git a/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/util/LexUtils.java b/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/util/LexUtils.java index 403ca3f9..84f67723 100644 --- a/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/util/LexUtils.java +++ b/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/util/LexUtils.java @@ -118,15 +118,14 @@ public static Supplier notFoundSupplier() { } - public static String getRootExceptionName(Throwable ex) { + public static Throwable getRootException(Throwable ex) { - if (ex == null) - return "UnknownException"; + if (ex == null) return null; while(ex.getCause() != null) ex = ex.getCause(); - return ex.getClass().getSimpleName(); + return ex; } } From 836f8b2daba532a909cfd1a2e742d2213979783a Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Sat, 20 Oct 2018 20:43:51 +0530 Subject: [PATCH 063/116] Renamed "exception" to "exceptionId" in error response --- .../exceptions/LemonReactiveErrorAttributes.java | 6 +++--- .../exceptions/DefaultExceptionHandlerControllerAdvice.java | 2 +- .../lemon/commonsweb/exceptions/LemonErrorAttributes.java | 6 +++--- .../spring/lemon/exceptions/ErrorResponse.java | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/exceptions/LemonReactiveErrorAttributes.java b/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/exceptions/LemonReactiveErrorAttributes.java index 607470c8..e96b7b3f 100644 --- a/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/exceptions/LemonReactiveErrorAttributes.java +++ b/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/exceptions/LemonReactiveErrorAttributes.java @@ -48,14 +48,14 @@ protected void addLemonErrorDetails( Throwable ex = getError(request); - errorAttributes.put("exception", exceptionCodeMaker.make(LexUtils.getRootException(ex))); + errorAttributes.put("exceptionId", exceptionCodeMaker.make(LexUtils.getRootException(ex))); errorResponseComposer.compose((T)ex).ifPresent(errorResponse -> { // check for nulls - errorResponse may have left something for the DefaultErrorAttributes - if (errorResponse.getException() != null) // In case of deserialized exception from Feign - errorAttributes.put("exception", errorResponse.getException()); + if (errorResponse.getExceptionId() != null) // In case of deserialized exception from Feign + errorAttributes.put("exceptionId", errorResponse.getExceptionId()); if (errorResponse.getMessage() != null) errorAttributes.put("message", errorResponse.getMessage()); diff --git a/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/exceptions/DefaultExceptionHandlerControllerAdvice.java b/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/exceptions/DefaultExceptionHandlerControllerAdvice.java index fbcd85bc..ef13f9a1 100644 --- a/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/exceptions/DefaultExceptionHandlerControllerAdvice.java +++ b/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/exceptions/DefaultExceptionHandlerControllerAdvice.java @@ -54,7 +54,7 @@ public ResponseEntity handleException(T ex) throws T { // We didn't do this inside compose because LemonErrorAttributes // and LemonReactiveErrorAttributes would do it differently - errorResponse.setException(exceptionCodeMaker.make(LexUtils.getRootException(ex))); + errorResponse.setExceptionId(exceptionCodeMaker.make(LexUtils.getRootException(ex))); return new ResponseEntity(errorResponse, HttpStatus.valueOf(errorResponse.getStatus())); } diff --git a/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/exceptions/LemonErrorAttributes.java b/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/exceptions/LemonErrorAttributes.java index f8a5265c..aa75e0d8 100644 --- a/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/exceptions/LemonErrorAttributes.java +++ b/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/exceptions/LemonErrorAttributes.java @@ -58,14 +58,14 @@ protected void addLemonErrorDetails( Throwable ex = getError(request); - errorAttributes.put("exception", exceptionCodeMaker.make(LexUtils.getRootException(ex))); + errorAttributes.put("exceptionId", exceptionCodeMaker.make(LexUtils.getRootException(ex))); errorResponseComposer.compose((T)ex).ifPresent(errorResponse -> { // check for null - errorResponse may have left something for the DefaultErrorAttributes - if (errorResponse.getException() != null) // In case of deserialized exception from Feign - errorAttributes.put("exception", errorResponse.getException()); + if (errorResponse.getExceptionId() != null) // In case of deserialized exception from Feign + errorAttributes.put("exceptionId", errorResponse.getExceptionId()); if (errorResponse.getMessage() != null) errorAttributes.put("message", errorResponse.getMessage()); diff --git a/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/ErrorResponse.java b/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/ErrorResponse.java index b591289b..6063e225 100644 --- a/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/ErrorResponse.java +++ b/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/ErrorResponse.java @@ -12,7 +12,7 @@ @Getter @Setter public class ErrorResponse { - private String exception; + private String exceptionId; private String error; private String message; private Integer status; // We'd need it as integer in JSON serialization From 8c45869e756930a82a73482f15951a9f089ce5cb Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Sun, 21 Oct 2018 09:51:29 +0530 Subject: [PATCH 064/116] Fixed objectName not getting prefixed before fieldname in ExplicitConstraintViolationException --- .../spring/lemon/exceptions/LemonFieldError.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/LemonFieldError.java b/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/LemonFieldError.java index bc47d047..1d4afcce 100644 --- a/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/LemonFieldError.java +++ b/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/LemonFieldError.java @@ -52,7 +52,7 @@ public static Collection getErrors(ExplicitConstraintViolationE return ex.getConstraintViolations().stream() .map(constraintViolation -> new LemonFieldError( - constraintViolation.getPropertyPath().toString(), + ex.getObjectName() + "." + constraintViolation.getPropertyPath().toString(), constraintViolation.getMessageTemplate(), constraintViolation.getMessage())) .collect(Collectors.toList()); From 499a5f0e2708dd7062b7b17b9afe94f73fac8aec Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Sun, 21 Oct 2018 16:47:52 +0530 Subject: [PATCH 065/116] Some improvements to ExplicitConstraintViolationException --- .../spring/lemondemo/entities/User.java | 3 +- .../spring/lemondemo/domain/User.java | 3 +- .../spring/lemondemo/BasicTests.java | 1 - .../lemon/commons/security/UserDto.java | 3 +- .../ExplicitConstraintViolationException.java | 35 ++++++++++++++----- .../lemon/exceptions/LemonFieldError.java | 12 ------- .../AbstractValidationExceptionHandler.java | 28 +++++++++++++++ .../ConstraintViolationExceptionHandler.java | 21 ++--------- ...itConstraintViolationExceptionHandler.java | 4 +-- .../WebExchangeBindExceptionHandler.java | 14 +------- .../lemon/exceptions/util/LexUtils.java | 13 +++---- 11 files changed, 72 insertions(+), 65 deletions(-) create mode 100644 spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/handlers/AbstractValidationExceptionHandler.java diff --git a/lemon-demo-jpa/src/main/java/com/naturalprogrammer/spring/lemondemo/entities/User.java b/lemon-demo-jpa/src/main/java/com/naturalprogrammer/spring/lemondemo/entities/User.java index 357af53f..b4b380d2 100644 --- a/lemon-demo-jpa/src/main/java/com/naturalprogrammer/spring/lemondemo/entities/User.java +++ b/lemon-demo-jpa/src/main/java/com/naturalprogrammer/spring/lemondemo/entities/User.java @@ -15,6 +15,7 @@ import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; +import lombok.ToString; @Entity @Table(name="usr") @@ -26,7 +27,7 @@ public class User extends AbstractUser { public static final int NAME_MIN = 1; public static final int NAME_MAX = 50; - @Getter @Setter + @Getter @Setter @ToString public static class Tag implements Serializable { private static final long serialVersionUID = -2129078111926834670L; diff --git a/lemon-demo-reactive/src/main/java/com/naturalprogrammer/spring/lemondemo/domain/User.java b/lemon-demo-reactive/src/main/java/com/naturalprogrammer/spring/lemondemo/domain/User.java index 7bace97b..20e12dfd 100644 --- a/lemon-demo-reactive/src/main/java/com/naturalprogrammer/spring/lemondemo/domain/User.java +++ b/lemon-demo-reactive/src/main/java/com/naturalprogrammer/spring/lemondemo/domain/User.java @@ -15,6 +15,7 @@ import lombok.Getter; import lombok.Setter; +import lombok.ToString; @Getter @Setter @TypeAlias("User") @@ -24,7 +25,7 @@ public class User extends AbstractMongoUser { public static final int NAME_MIN = 1; public static final int NAME_MAX = 50; - @Getter @Setter + @Getter @Setter @ToString public static class Tag implements Serializable { private static final long serialVersionUID = -2129078111926834670L; diff --git a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/BasicTests.java b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/BasicTests.java index ef1e0981..7e1b0daf 100644 --- a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/BasicTests.java +++ b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/BasicTests.java @@ -4,7 +4,6 @@ import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.CLIENT; import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.TOKENS; import static com.naturalprogrammer.spring.lemondemo.controllers.MyController.BASE_URI; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; import org.junit.Test; diff --git a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/UserDto.java b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/UserDto.java index 7e820982..f2825e27 100644 --- a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/UserDto.java +++ b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/UserDto.java @@ -8,12 +8,13 @@ import lombok.Getter; import lombok.Setter; +import lombok.ToString; /** * A lighter User class, * mainly used for holding logged-in user data */ -@Getter @Setter +@Getter @Setter @ToString public class UserDto implements Serializable { private static final long serialVersionUID = -9134054705405149534L; diff --git a/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/ExplicitConstraintViolationException.java b/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/ExplicitConstraintViolationException.java index f00122b1..391dd140 100644 --- a/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/ExplicitConstraintViolationException.java +++ b/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/ExplicitConstraintViolationException.java @@ -1,21 +1,40 @@ package com.naturalprogrammer.spring.lemon.exceptions; +import java.util.ArrayList; +import java.util.List; import java.util.Set; +import java.util.stream.Collectors; import javax.validation.ConstraintViolation; -import javax.validation.ConstraintViolationException; import lombok.Getter; -public class ExplicitConstraintViolationException extends ConstraintViolationException { +@Getter +public class ExplicitConstraintViolationException extends RuntimeException { private static final long serialVersionUID = 3723548255231135762L; - @Getter - private final String objectName; + // list of errors + private List errors = new ArrayList<>(10); + + public ExplicitConstraintViolationException addErrors(Set> constraintViolations, String objectName) { + + errors.addAll(constraintViolations.stream() + .map(constraintViolation -> + new LemonFieldError( + objectName + "." + constraintViolation.getPropertyPath().toString(), + constraintViolation.getMessageTemplate(), + constraintViolation.getMessage())) + .collect(Collectors.toList())); + + return this; + } - public ExplicitConstraintViolationException(Set> constraintViolations, String objectName) { - super(constraintViolations); - this.objectName = objectName; - } + /** + * Throws the exception, if there are accumulated errors + */ + public void go() { + if (!errors.isEmpty()) + throw this; + } } diff --git a/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/LemonFieldError.java b/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/LemonFieldError.java index 1d4afcce..31063ae9 100644 --- a/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/LemonFieldError.java +++ b/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/LemonFieldError.java @@ -1,6 +1,5 @@ package com.naturalprogrammer.spring.lemon.exceptions; -import java.util.Collection; import java.util.List; import java.util.Set; import java.util.stream.Collectors; @@ -47,17 +46,6 @@ public static List getErrors( } - public static Collection getErrors(ExplicitConstraintViolationException ex) { - - return ex.getConstraintViolations().stream() - .map(constraintViolation -> - new LemonFieldError( - ex.getObjectName() + "." + constraintViolation.getPropertyPath().toString(), - constraintViolation.getMessageTemplate(), - constraintViolation.getMessage())) - .collect(Collectors.toList()); - } - /** * Converts a ConstraintViolation * to a FieldError diff --git a/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/handlers/AbstractValidationExceptionHandler.java b/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/handlers/AbstractValidationExceptionHandler.java new file mode 100644 index 00000000..e7be3af1 --- /dev/null +++ b/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/handlers/AbstractValidationExceptionHandler.java @@ -0,0 +1,28 @@ +package com.naturalprogrammer.spring.lemon.exceptions.handlers; + +import org.springframework.core.Ordered; +import org.springframework.core.annotation.Order; +import org.springframework.http.HttpStatus; + +import com.naturalprogrammer.spring.lemon.exceptions.util.LexUtils; + +/** + * Extend this for any exception handler that should return a 400 response + */ +@Order(Ordered.LOWEST_PRECEDENCE) +public abstract class AbstractValidationExceptionHandler extends AbstractExceptionHandler { + + public AbstractValidationExceptionHandler(Class exceptionClass) { + super(exceptionClass); + } + + @Override + public HttpStatus getStatus(T ex) { + return HttpStatus.UNPROCESSABLE_ENTITY; + } + + @Override + public String getMessage(T ex) { + return LexUtils.getMessage("com.naturalprogrammer.spring.validationError"); + } +} diff --git a/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/handlers/ConstraintViolationExceptionHandler.java b/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/handlers/ConstraintViolationExceptionHandler.java index 5e0e1c1f..83c282e5 100644 --- a/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/handlers/ConstraintViolationExceptionHandler.java +++ b/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/handlers/ConstraintViolationExceptionHandler.java @@ -6,15 +6,13 @@ import org.springframework.core.Ordered; import org.springframework.core.annotation.Order; -import org.springframework.http.HttpStatus; import org.springframework.stereotype.Component; import com.naturalprogrammer.spring.lemon.exceptions.LemonFieldError; -import com.naturalprogrammer.spring.lemon.exceptions.util.LexUtils; @Component @Order(Ordered.LOWEST_PRECEDENCE) -public class ConstraintViolationExceptionHandler extends AbstractExceptionHandler { +public class ConstraintViolationExceptionHandler extends AbstractValidationExceptionHandler { public ConstraintViolationExceptionHandler() { @@ -22,22 +20,9 @@ public ConstraintViolationExceptionHandler() { log.info("Created"); } - public ConstraintViolationExceptionHandler(Class exceptionClass) { - super(exceptionClass); - } - - @Override - public HttpStatus getStatus(E ex) { - return HttpStatus.UNPROCESSABLE_ENTITY; - } - @Override - public Collection getErrors(E ex) { + public Collection getErrors(ConstraintViolationException ex) { return LemonFieldError.getErrors(ex.getConstraintViolations()); } - - @Override - public String getMessage(E ex) { - return LexUtils.getMessage("com.naturalprogrammer.spring.validationError"); - } + } diff --git a/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/handlers/ExplicitConstraintViolationExceptionHandler.java b/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/handlers/ExplicitConstraintViolationExceptionHandler.java index b257d567..6902f5d0 100644 --- a/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/handlers/ExplicitConstraintViolationExceptionHandler.java +++ b/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/handlers/ExplicitConstraintViolationExceptionHandler.java @@ -12,7 +12,7 @@ @Component @Order(Ordered.LOWEST_PRECEDENCE) public class ExplicitConstraintViolationExceptionHandler - extends ConstraintViolationExceptionHandler { + extends AbstractValidationExceptionHandler { public ExplicitConstraintViolationExceptionHandler() { @@ -22,6 +22,6 @@ public ExplicitConstraintViolationExceptionHandler() { @Override public Collection getErrors(ExplicitConstraintViolationException ex) { - return LemonFieldError.getErrors(ex); + return ex.getErrors(); } } diff --git a/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/handlers/WebExchangeBindExceptionHandler.java b/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/handlers/WebExchangeBindExceptionHandler.java index 18973e98..1483e576 100644 --- a/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/handlers/WebExchangeBindExceptionHandler.java +++ b/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/handlers/WebExchangeBindExceptionHandler.java @@ -4,16 +4,14 @@ import org.springframework.core.Ordered; import org.springframework.core.annotation.Order; -import org.springframework.http.HttpStatus; import org.springframework.stereotype.Component; import org.springframework.web.bind.support.WebExchangeBindException; import com.naturalprogrammer.spring.lemon.exceptions.LemonFieldError; -import com.naturalprogrammer.spring.lemon.exceptions.util.LexUtils; @Component @Order(Ordered.LOWEST_PRECEDENCE) -public class WebExchangeBindExceptionHandler extends AbstractExceptionHandler { +public class WebExchangeBindExceptionHandler extends AbstractValidationExceptionHandler { public WebExchangeBindExceptionHandler() { @@ -21,18 +19,8 @@ public WebExchangeBindExceptionHandler() { log.info("Created"); } - @Override - public HttpStatus getStatus(WebExchangeBindException ex) { - return HttpStatus.UNPROCESSABLE_ENTITY; - } - @Override public Collection getErrors(WebExchangeBindException ex) { return LemonFieldError.getErrors(ex); } - - @Override - public String getMessage(WebExchangeBindException ex) { - return LexUtils.getMessage("com.naturalprogrammer.spring.validationError"); - } } diff --git a/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/util/LexUtils.java b/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/util/LexUtils.java index 84f67723..5be39c67 100644 --- a/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/util/LexUtils.java +++ b/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/util/LexUtils.java @@ -1,10 +1,8 @@ package com.naturalprogrammer.spring.lemon.exceptions.util; -import java.util.Set; import java.util.function.Supplier; import javax.annotation.PostConstruct; -import javax.validation.ConstraintViolation; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -67,14 +65,13 @@ public static String getMessage(String messageKey, Object... args) { /** - * Creates a MultiErrorException out of the given parameters + * Validates the given object and throws ExplicitConstraintViolationException in case of errors */ - public static void validate(String name, T object, Class... groups) { - - Set> violations = validator.validate(object, groups); + public static void validate(String objectName, T object, Class... groups) { - if (!violations.isEmpty()) - throw new ExplicitConstraintViolationException(violations, name); + new ExplicitConstraintViolationException() + .addErrors(validator.validate(object, groups), objectName) + .go(); } From 063fe2dba9d94d2de1e49377d2398890942a7626 Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Sun, 21 Oct 2018 18:56:32 +0530 Subject: [PATCH 066/116] Customized supplying exceptionId --- ...LemonCommonsReactiveAutoConfiguration.java | 7 ++----- .../LemonReactiveErrorAttributes.java | 14 +++++-------- .../LemonCommonsWebAutoConfiguration.java | 12 ++++------- ...faultExceptionHandlerControllerAdvice.java | 13 +----------- .../exceptions/LemonErrorAttributes.java | 14 +++++-------- ...onCodeMaker.java => ExceptionIdMaker.java} | 2 +- .../LemonExceptionsAutoConfiguration.java | 14 +++++++------ .../handlers/AbstractExceptionHandler.java | 8 ++++++- .../lemon/exceptions/util/LexUtils.java | 21 ++++++++++++++++--- 9 files changed, 51 insertions(+), 54 deletions(-) rename spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/{ExceptionCodeMaker.java => ExceptionIdMaker.java} (70%) diff --git a/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/LemonCommonsReactiveAutoConfiguration.java b/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/LemonCommonsReactiveAutoConfiguration.java index f68deb30..507cdf11 100644 --- a/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/LemonCommonsReactiveAutoConfiguration.java +++ b/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/LemonCommonsReactiveAutoConfiguration.java @@ -34,7 +34,6 @@ import com.naturalprogrammer.spring.lemon.commonsreactive.security.LemonReactiveCorsConfig; import com.naturalprogrammer.spring.lemon.commonsreactive.util.LecrUtils; import com.naturalprogrammer.spring.lemon.exceptions.ErrorResponseComposer; -import com.naturalprogrammer.spring.lemon.exceptions.ExceptionCodeMaker; import com.naturalprogrammer.spring.lemon.exceptions.util.LexUtils; @Configuration @@ -60,12 +59,10 @@ public LemonCommonsReactiveAutoConfiguration() { @Bean @ConditionalOnMissingBean(ErrorAttributes.class) public - ErrorAttributes errorAttributes( - ErrorResponseComposer errorResponseComposer, - ExceptionCodeMaker exceptionCodeMaker) { + ErrorAttributes errorAttributes(ErrorResponseComposer errorResponseComposer) { log.info("Configuring LemonErrorAttributes"); - return new LemonReactiveErrorAttributes(errorResponseComposer, exceptionCodeMaker); + return new LemonReactiveErrorAttributes(errorResponseComposer); } diff --git a/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/exceptions/LemonReactiveErrorAttributes.java b/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/exceptions/LemonReactiveErrorAttributes.java index e96b7b3f..6acc87a7 100644 --- a/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/exceptions/LemonReactiveErrorAttributes.java +++ b/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/exceptions/LemonReactiveErrorAttributes.java @@ -8,7 +8,6 @@ import org.springframework.web.reactive.function.server.ServerRequest; import com.naturalprogrammer.spring.lemon.exceptions.ErrorResponseComposer; -import com.naturalprogrammer.spring.lemon.exceptions.ExceptionCodeMaker; import com.naturalprogrammer.spring.lemon.exceptions.util.LexUtils; public class LemonReactiveErrorAttributes extends DefaultErrorAttributes { @@ -19,14 +18,10 @@ public class LemonReactiveErrorAttributes extends DefaultEr * Component that actually builds the error response */ private ErrorResponseComposer errorResponseComposer; - private ExceptionCodeMaker exceptionCodeMaker; - public LemonReactiveErrorAttributes( - ErrorResponseComposer errorResponseComposer, - ExceptionCodeMaker exceptionCodeMaker) { + public LemonReactiveErrorAttributes(ErrorResponseComposer errorResponseComposer) { this.errorResponseComposer = errorResponseComposer; - this.exceptionCodeMaker = exceptionCodeMaker; log.info("Created"); } @@ -48,13 +43,11 @@ protected void addLemonErrorDetails( Throwable ex = getError(request); - errorAttributes.put("exceptionId", exceptionCodeMaker.make(LexUtils.getRootException(ex))); - errorResponseComposer.compose((T)ex).ifPresent(errorResponse -> { // check for nulls - errorResponse may have left something for the DefaultErrorAttributes - if (errorResponse.getExceptionId() != null) // In case of deserialized exception from Feign + if (errorResponse.getExceptionId() != null) errorAttributes.put("exceptionId", errorResponse.getExceptionId()); if (errorResponse.getMessage() != null) @@ -70,5 +63,8 @@ protected void addLemonErrorDetails( if (errorResponse.getErrors() != null) errorAttributes.put("errors", errorResponse.getErrors()); }); + + if (errorAttributes.get("exceptionId") == null) + errorAttributes.put("exceptionId", LexUtils.getExceptionId(ex)); } } diff --git a/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/LemonCommonsWebAutoConfiguration.java b/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/LemonCommonsWebAutoConfiguration.java index c8bf926e..c0fec38a 100644 --- a/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/LemonCommonsWebAutoConfiguration.java +++ b/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/LemonCommonsWebAutoConfiguration.java @@ -35,7 +35,6 @@ import com.naturalprogrammer.spring.lemon.commonsweb.security.LemonWebSecurityConfig; import com.naturalprogrammer.spring.lemon.commonsweb.util.LecwUtils; import com.naturalprogrammer.spring.lemon.exceptions.ErrorResponseComposer; -import com.naturalprogrammer.spring.lemon.exceptions.ExceptionCodeMaker; @Configuration @EnableSpringDataWebSupport @@ -87,11 +86,10 @@ public MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter( @ConditionalOnMissingBean(DefaultExceptionHandlerControllerAdvice.class) public DefaultExceptionHandlerControllerAdvice defaultExceptionHandlerControllerAdvice( - ErrorResponseComposer errorResponseComposer, - ExceptionCodeMaker exceptionCodeMaker) { + ErrorResponseComposer errorResponseComposer) { log.info("Configuring DefaultExceptionHandlerControllerAdvice"); - return new DefaultExceptionHandlerControllerAdvice(errorResponseComposer, exceptionCodeMaker); + return new DefaultExceptionHandlerControllerAdvice(errorResponseComposer); } /** @@ -100,12 +98,10 @@ DefaultExceptionHandlerControllerAdvice defaultExceptionHandlerControllerAdvi @Bean @ConditionalOnMissingBean(ErrorAttributes.class) public - ErrorAttributes errorAttributes( - ErrorResponseComposer errorResponseComposer, - ExceptionCodeMaker exceptionCodeMaker) { + ErrorAttributes errorAttributes(ErrorResponseComposer errorResponseComposer) { log.info("Configuring LemonErrorAttributes"); - return new LemonErrorAttributes(errorResponseComposer, exceptionCodeMaker); + return new LemonErrorAttributes(errorResponseComposer); } /** diff --git a/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/exceptions/DefaultExceptionHandlerControllerAdvice.java b/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/exceptions/DefaultExceptionHandlerControllerAdvice.java index ef13f9a1..250912fa 100644 --- a/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/exceptions/DefaultExceptionHandlerControllerAdvice.java +++ b/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/exceptions/DefaultExceptionHandlerControllerAdvice.java @@ -10,8 +10,6 @@ import com.naturalprogrammer.spring.lemon.exceptions.ErrorResponse; import com.naturalprogrammer.spring.lemon.exceptions.ErrorResponseComposer; -import com.naturalprogrammer.spring.lemon.exceptions.ExceptionCodeMaker; -import com.naturalprogrammer.spring.lemon.exceptions.util.LexUtils; /** * Handles exceptions thrown from in controllers or inner routines @@ -25,14 +23,10 @@ public class DefaultExceptionHandlerControllerAdvice { * Component that actually builds the error response */ private ErrorResponseComposer errorResponseComposer; - private ExceptionCodeMaker exceptionCodeMaker; - public DefaultExceptionHandlerControllerAdvice( - ErrorResponseComposer errorResponseComposer, - ExceptionCodeMaker exceptionCodeMaker) { + public DefaultExceptionHandlerControllerAdvice(ErrorResponseComposer errorResponseComposer) { this.errorResponseComposer = errorResponseComposer; - this.exceptionCodeMaker = exceptionCodeMaker; log.info("Created"); } @@ -51,11 +45,6 @@ public ResponseEntity handleException(T ex) throws T { throw ex; log.warn("Handling exception", ex); - - // We didn't do this inside compose because LemonErrorAttributes - // and LemonReactiveErrorAttributes would do it differently - errorResponse.setExceptionId(exceptionCodeMaker.make(LexUtils.getRootException(ex))); - return new ResponseEntity(errorResponse, HttpStatus.valueOf(errorResponse.getStatus())); } } diff --git a/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/exceptions/LemonErrorAttributes.java b/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/exceptions/LemonErrorAttributes.java index aa75e0d8..4c85d3f7 100644 --- a/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/exceptions/LemonErrorAttributes.java +++ b/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/exceptions/LemonErrorAttributes.java @@ -8,7 +8,6 @@ import org.springframework.web.context.request.WebRequest; import com.naturalprogrammer.spring.lemon.exceptions.ErrorResponseComposer; -import com.naturalprogrammer.spring.lemon.exceptions.ExceptionCodeMaker; import com.naturalprogrammer.spring.lemon.exceptions.util.LexUtils; /** @@ -23,14 +22,10 @@ public class LemonErrorAttributes extends DefaultErrorAttri static final String HTTP_STATUS_KEY = "httpStatus"; private ErrorResponseComposer errorResponseComposer; - private ExceptionCodeMaker exceptionCodeMaker; - public LemonErrorAttributes( - ErrorResponseComposer errorResponseComposer, - ExceptionCodeMaker exceptionCodeMaker) { + public LemonErrorAttributes(ErrorResponseComposer errorResponseComposer) { this.errorResponseComposer = errorResponseComposer; - this.exceptionCodeMaker = exceptionCodeMaker; log.info("Created"); } @@ -58,13 +53,11 @@ protected void addLemonErrorDetails( Throwable ex = getError(request); - errorAttributes.put("exceptionId", exceptionCodeMaker.make(LexUtils.getRootException(ex))); - errorResponseComposer.compose((T)ex).ifPresent(errorResponse -> { // check for null - errorResponse may have left something for the DefaultErrorAttributes - if (errorResponse.getExceptionId() != null) // In case of deserialized exception from Feign + if (errorResponse.getExceptionId() != null) errorAttributes.put("exceptionId", errorResponse.getExceptionId()); if (errorResponse.getMessage() != null) @@ -81,5 +74,8 @@ protected void addLemonErrorDetails( if (errorResponse.getErrors() != null) errorAttributes.put("errors", errorResponse.getErrors()); }); + + if (errorAttributes.get("exceptionId") == null) + errorAttributes.put("exceptionId", LexUtils.getExceptionId(ex)); } } diff --git a/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/ExceptionCodeMaker.java b/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/ExceptionIdMaker.java similarity index 70% rename from spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/ExceptionCodeMaker.java rename to spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/ExceptionIdMaker.java index 8b1daffa..8fbe17ed 100644 --- a/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/ExceptionCodeMaker.java +++ b/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/ExceptionIdMaker.java @@ -1,7 +1,7 @@ package com.naturalprogrammer.spring.lemon.exceptions; @FunctionalInterface -public interface ExceptionCodeMaker { +public interface ExceptionIdMaker { String make(Throwable t); } diff --git a/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/LemonExceptionsAutoConfiguration.java b/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/LemonExceptionsAutoConfiguration.java index 58976699..25d0259f 100644 --- a/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/LemonExceptionsAutoConfiguration.java +++ b/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/LemonExceptionsAutoConfiguration.java @@ -47,22 +47,24 @@ ErrorResponseComposer errorResponseComposer(List> * Configures ExceptionCodeMaker if missing */ @Bean - @ConditionalOnMissingBean(ExceptionCodeMaker.class) - public ExceptionCodeMaker exceptionCodeMaker() { + @ConditionalOnMissingBean(ExceptionIdMaker.class) + public ExceptionIdMaker exceptionIdMaker() { - log.info("Configuring ExceptionCodeMaker"); + log.info("Configuring ExceptionIdMaker"); return ex -> ex.getClass().getSimpleName(); } /** - * Configures LemonUtils + * Configures LexUtils */ @Bean - public LexUtils lexUtils(MessageSource messageSource, LocalValidatorFactoryBean validator) { + public LexUtils lexUtils(MessageSource messageSource, + LocalValidatorFactoryBean validator, + ExceptionIdMaker exceptionIdMaker) { log.info("Configuring LexUtils"); - return new LexUtils(messageSource, validator); + return new LexUtils(messageSource, validator, exceptionIdMaker); } /** diff --git a/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/handlers/AbstractExceptionHandler.java b/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/handlers/AbstractExceptionHandler.java index 4548f066..a7615bfb 100644 --- a/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/handlers/AbstractExceptionHandler.java +++ b/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/handlers/AbstractExceptionHandler.java @@ -8,6 +8,7 @@ import com.naturalprogrammer.spring.lemon.exceptions.ErrorResponse; import com.naturalprogrammer.spring.lemon.exceptions.LemonFieldError; +import com.naturalprogrammer.spring.lemon.exceptions.util.LexUtils; /** * Extend this to code an exception handler @@ -26,6 +27,10 @@ public Class getExceptionClass() { return exceptionClass; } + protected String getExceptionId(T ex) { + return LexUtils.getExceptionId(ex); + } + protected String getMessage(T ex) { return ex.getMessage(); } @@ -39,9 +44,10 @@ protected Collection getErrors(T ex) { } public ErrorResponse getErrorResponse(T ex) { - + ErrorResponse errorResponse = new ErrorResponse(); + errorResponse.setExceptionId(getExceptionId(ex)); errorResponse.setMessage(getMessage(ex)); HttpStatus status = getStatus(ex); diff --git a/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/util/LexUtils.java b/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/util/LexUtils.java index 5be39c67..51581968 100644 --- a/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/util/LexUtils.java +++ b/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/util/LexUtils.java @@ -11,6 +11,7 @@ import org.springframework.http.HttpStatus; import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean; +import com.naturalprogrammer.spring.lemon.exceptions.ExceptionIdMaker; import com.naturalprogrammer.spring.lemon.exceptions.ExplicitConstraintViolationException; import com.naturalprogrammer.spring.lemon.exceptions.MultiErrorException; @@ -25,15 +26,20 @@ public class LexUtils { private static MessageSource messageSource; private static LocalValidatorFactoryBean validator; + private static ExceptionIdMaker exceptionIdMaker; + public static final MultiErrorException NOT_FOUND_EXCEPTION = new MultiErrorException(); /** * Constructor */ - public LexUtils(MessageSource messageSource, LocalValidatorFactoryBean validator) { + public LexUtils(MessageSource messageSource, + LocalValidatorFactoryBean validator, + ExceptionIdMaker exceptionIdMaker) { LexUtils.messageSource = messageSource; LexUtils.validator = validator; + LexUtils.exceptionIdMaker = exceptionIdMaker; log.info("Created"); } @@ -115,7 +121,17 @@ public static Supplier notFoundSupplier() { } - public static Throwable getRootException(Throwable ex) { + public static String getExceptionId(Throwable ex) { + + Throwable root = getRootException(ex); + if (root == null) + return null; + + return exceptionIdMaker.make(root); + } + + + private static Throwable getRootException(Throwable ex) { if (ex == null) return null; @@ -124,5 +140,4 @@ public static Throwable getRootException(Throwable ex) { return ex; } - } From 5b950bb3e1f957cf8fdceba9ab2f3d31bcf8db6c Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Sun, 21 Oct 2018 19:13:01 +0530 Subject: [PATCH 067/116] Replaced ExplicitConstraintViolationException with MultiErrorException --- .../ExplicitConstraintViolationException.java | 40 ------------------- .../lemon/exceptions/MultiErrorException.java | 32 +++++++++++++++ ...itConstraintViolationExceptionHandler.java | 27 ------------- .../handlers/MultiErrorExceptionHandler.java | 9 +++++ .../lemon/exceptions/util/LexUtils.java | 4 +- 5 files changed, 43 insertions(+), 69 deletions(-) delete mode 100644 spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/ExplicitConstraintViolationException.java delete mode 100644 spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/handlers/ExplicitConstraintViolationExceptionHandler.java diff --git a/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/ExplicitConstraintViolationException.java b/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/ExplicitConstraintViolationException.java deleted file mode 100644 index 391dd140..00000000 --- a/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/ExplicitConstraintViolationException.java +++ /dev/null @@ -1,40 +0,0 @@ -package com.naturalprogrammer.spring.lemon.exceptions; - -import java.util.ArrayList; -import java.util.List; -import java.util.Set; -import java.util.stream.Collectors; - -import javax.validation.ConstraintViolation; - -import lombok.Getter; - -@Getter -public class ExplicitConstraintViolationException extends RuntimeException { - - private static final long serialVersionUID = 3723548255231135762L; - - // list of errors - private List errors = new ArrayList<>(10); - - public ExplicitConstraintViolationException addErrors(Set> constraintViolations, String objectName) { - - errors.addAll(constraintViolations.stream() - .map(constraintViolation -> - new LemonFieldError( - objectName + "." + constraintViolation.getPropertyPath().toString(), - constraintViolation.getMessageTemplate(), - constraintViolation.getMessage())) - .collect(Collectors.toList())); - - return this; - } - - /** - * Throws the exception, if there are accumulated errors - */ - public void go() { - if (!errors.isEmpty()) - throw this; - } -} diff --git a/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/MultiErrorException.java b/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/MultiErrorException.java index 78ea03ef..c49c4a26 100644 --- a/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/MultiErrorException.java +++ b/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/MultiErrorException.java @@ -2,6 +2,10 @@ import java.util.ArrayList; import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +import javax.validation.ConstraintViolation; import org.springframework.http.HttpStatus; @@ -26,11 +30,19 @@ public class MultiErrorException extends RuntimeException { // HTTP Status code to be returned private HttpStatus status = HttpStatus.UNPROCESSABLE_ENTITY; + // Set this if you need to customize exceptionId + private String exceptionId = null; + public MultiErrorException httpStatus(HttpStatus status) { this.status = status; return this; } + public MultiErrorException exceptionId(String exceptionId) { + this.exceptionId = exceptionId; + return this; + } + /** * Adds a field-error if the given condition isn't true */ @@ -62,6 +74,26 @@ public MultiErrorException validate(boolean valid, return validate(null, valid, messageKey, args); } + /** + * Adds constraint violations + * + * @param constraintViolations + * @param objectName + * @return + */ + public MultiErrorException addErrors(Set> constraintViolations, String objectName) { + + errors.addAll(constraintViolations.stream() + .map(constraintViolation -> + new LemonFieldError( + objectName + "." + constraintViolation.getPropertyPath().toString(), + constraintViolation.getMessageTemplate(), + constraintViolation.getMessage())) + .collect(Collectors.toList())); + + return this; + } + /** * Overrides the standard getMessage */ diff --git a/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/handlers/ExplicitConstraintViolationExceptionHandler.java b/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/handlers/ExplicitConstraintViolationExceptionHandler.java deleted file mode 100644 index 6902f5d0..00000000 --- a/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/handlers/ExplicitConstraintViolationExceptionHandler.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.naturalprogrammer.spring.lemon.exceptions.handlers; - -import java.util.Collection; - -import org.springframework.core.Ordered; -import org.springframework.core.annotation.Order; -import org.springframework.stereotype.Component; - -import com.naturalprogrammer.spring.lemon.exceptions.ExplicitConstraintViolationException; -import com.naturalprogrammer.spring.lemon.exceptions.LemonFieldError; - -@Component -@Order(Ordered.LOWEST_PRECEDENCE) -public class ExplicitConstraintViolationExceptionHandler - extends AbstractValidationExceptionHandler { - - public ExplicitConstraintViolationExceptionHandler() { - - super(ExplicitConstraintViolationException.class); - log.info("Created"); - } - - @Override - public Collection getErrors(ExplicitConstraintViolationException ex) { - return ex.getErrors(); - } -} diff --git a/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/handlers/MultiErrorExceptionHandler.java b/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/handlers/MultiErrorExceptionHandler.java index 82e0925a..72ea980b 100644 --- a/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/handlers/MultiErrorExceptionHandler.java +++ b/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/handlers/MultiErrorExceptionHandler.java @@ -20,6 +20,15 @@ public MultiErrorExceptionHandler() { log.info("Created"); } + @Override + public String getExceptionId(MultiErrorException ex) { + + if (ex.getExceptionId() == null) + return super.getExceptionId(ex); + + return ex.getExceptionId(); + } + @Override public String getMessage(MultiErrorException ex) { return ex.getMessage(); diff --git a/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/util/LexUtils.java b/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/util/LexUtils.java index 51581968..5320c90d 100644 --- a/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/util/LexUtils.java +++ b/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/util/LexUtils.java @@ -12,7 +12,6 @@ import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean; import com.naturalprogrammer.spring.lemon.exceptions.ExceptionIdMaker; -import com.naturalprogrammer.spring.lemon.exceptions.ExplicitConstraintViolationException; import com.naturalprogrammer.spring.lemon.exceptions.MultiErrorException; /** @@ -75,7 +74,8 @@ public static String getMessage(String messageKey, Object... args) { */ public static void validate(String objectName, T object, Class... groups) { - new ExplicitConstraintViolationException() + new MultiErrorException() + .exceptionId("ConstraintViolationException") .addErrors(validator.validate(object, groups), objectName) .go(); } From 8ded0b90cc46b82301a09b697018219475103945 Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Sun, 21 Oct 2018 19:44:15 +0530 Subject: [PATCH 068/116] Enhanced manual bean validation exceptionId --- .../spring/lemon/exceptions/util/LexUtils.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/util/LexUtils.java b/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/util/LexUtils.java index 5320c90d..b836f753 100644 --- a/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/util/LexUtils.java +++ b/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/util/LexUtils.java @@ -3,6 +3,7 @@ import java.util.function.Supplier; import javax.annotation.PostConstruct; +import javax.validation.ConstraintViolationException; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -75,7 +76,7 @@ public static String getMessage(String messageKey, Object... args) { public static void validate(String objectName, T object, Class... groups) { new MultiErrorException() - .exceptionId("ConstraintViolationException") + .exceptionId(getExceptionId(new ConstraintViolationException(null))) .addErrors(validator.validate(object, groups), objectName) .go(); } From 5e28c1c72b727d0121cd947adf057006225a6fdb Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Mon, 22 Oct 2018 22:00:49 +0530 Subject: [PATCH 069/116] Fixed login failure handler to have Simple... rather than OAuth2... --- .../spring/lemon/security/LemonJpaSecurityConfig.java | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonJpaSecurityConfig.java b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonJpaSecurityConfig.java index cd1c36c1..4df47b69 100644 --- a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonJpaSecurityConfig.java +++ b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonJpaSecurityConfig.java @@ -6,6 +6,7 @@ import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.web.authentication.AuthenticationFailureHandler; +import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; import com.naturalprogrammer.spring.lemon.commons.LemonProperties; @@ -25,7 +26,6 @@ public class LemonJpaSecurityConfig extends LemonWebSecurityConfig { private LemonProperties properties; private LemonUserDetailsService userDetailsService; private LemonAuthenticationSuccessHandler authenticationSuccessHandler; - private AuthenticationFailureHandler authenticationFailureHandler; private LemonOidcUserService oidcUserService; private LemonOAuth2UserService oauth2UserService; private OAuth2AuthenticationSuccessHandler oauth2AuthenticationSuccessHandler; @@ -34,7 +34,7 @@ public class LemonJpaSecurityConfig extends LemonWebSecurityConfig { @Autowired public void createLemonSecurityConfig(LemonProperties properties, LemonUserDetailsService userDetailsService, - LemonAuthenticationSuccessHandler authenticationSuccessHandler, AuthenticationFailureHandler authenticationFailureHandler, + LemonAuthenticationSuccessHandler authenticationSuccessHandler, LemonOidcUserService oidcUserService, LemonOAuth2UserService oauth2UserService, OAuth2AuthenticationSuccessHandler oauth2AuthenticationSuccessHandler, @@ -44,7 +44,6 @@ public void createLemonSecurityConfig(LemonProperties properties, LemonUserDetai this.properties = properties; this.userDetailsService = userDetailsService; this.authenticationSuccessHandler = authenticationSuccessHandler; - this.authenticationFailureHandler = authenticationFailureHandler; this.oidcUserService = oidcUserService; this.oauth2UserService = oauth2UserService; this.oauth2AuthenticationSuccessHandler = oauth2AuthenticationSuccessHandler; @@ -87,7 +86,7 @@ protected void login(HttpSecurity http) throws Exception { * that url if login fails. Instead, we need to send * 401. So, let's set failureHandler instead. *******************************************/ - .failureHandler(authenticationFailureHandler); + .failureHandler(new SimpleUrlAuthenticationFailureHandler()); } From bca5a46b5652c8dfb2ed6666fee99f951ef13c90 Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Mon, 22 Oct 2018 22:16:26 +0530 Subject: [PATCH 070/116] ExceptionIdMaker now takes care of null exceptions --- .../exceptions/LemonExceptionsAutoConfiguration.java | 8 +++++++- .../spring/lemon/exceptions/util/LexUtils.java | 3 --- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/LemonExceptionsAutoConfiguration.java b/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/LemonExceptionsAutoConfiguration.java index 25d0259f..30d3999f 100644 --- a/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/LemonExceptionsAutoConfiguration.java +++ b/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/LemonExceptionsAutoConfiguration.java @@ -51,7 +51,13 @@ ErrorResponseComposer errorResponseComposer(List> public ExceptionIdMaker exceptionIdMaker() { log.info("Configuring ExceptionIdMaker"); - return ex -> ex.getClass().getSimpleName(); + return ex -> { + + if (ex == null) + return null; + + return ex.getClass().getSimpleName(); + }; } diff --git a/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/util/LexUtils.java b/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/util/LexUtils.java index b836f753..b63fad24 100644 --- a/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/util/LexUtils.java +++ b/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/util/LexUtils.java @@ -125,9 +125,6 @@ public static Supplier notFoundSupplier() { public static String getExceptionId(Throwable ex) { Throwable root = getRootException(ex); - if (root == null) - return null; - return exceptionIdMaker.make(root); } From 0ab8eafeb2349094c21acd918d566d33b1c8b80f Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Tue, 23 Oct 2018 12:14:05 +0530 Subject: [PATCH 071/116] Supported seamless integration of custom and bean validation --- .../lemon/exceptions/MultiErrorException.java | 69 ++++++++++++------- .../lemon/exceptions/util/LexUtils.java | 31 +++++---- .../spring/lemon/LemonService.java | 4 +- .../lemonreactive/LemonReactiveService.java | 6 +- 4 files changed, 66 insertions(+), 44 deletions(-) diff --git a/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/MultiErrorException.java b/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/MultiErrorException.java index c49c4a26..6548489a 100644 --- a/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/MultiErrorException.java +++ b/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/MultiErrorException.java @@ -11,6 +11,7 @@ import com.naturalprogrammer.spring.lemon.exceptions.util.LexUtils; +import lombok.AccessLevel; import lombok.Getter; /** @@ -33,6 +34,23 @@ public class MultiErrorException extends RuntimeException { // Set this if you need to customize exceptionId private String exceptionId = null; + // Set this if you're doing bean validation and using validation groups + @Getter(AccessLevel.NONE) + private Class[] validationGroups = {}; + + /** + * Overrides the standard getMessage + */ + @Override + public String getMessage() { + + if (errors.isEmpty()) + return null; + + // return the first message + return errors.get(0).getMessage(); + } + public MultiErrorException httpStatus(HttpStatus status) { this.status = status; return this; @@ -43,10 +61,15 @@ public MultiErrorException exceptionId(String exceptionId) { return this; } + public MultiErrorException validationGroups(Class... groups) { + validationGroups = groups; + return this; + } + /** * Adds a field-error if the given condition isn't true */ - public MultiErrorException validate(String fieldName, boolean valid, + public MultiErrorException validateField(String fieldName, boolean valid, String messageKey, Object... args) { if (!valid) @@ -56,14 +79,6 @@ public MultiErrorException validate(String fieldName, boolean valid, return this; } - /** - * Throws the exception, if there are accumulated errors - */ - public void go() { - if (!errors.isEmpty()) - throw this; - } - /** * Adds a global-error if the given condition isn't true */ @@ -71,9 +86,26 @@ public MultiErrorException validate(boolean valid, String messageKey, Object... args) { // delegate - return validate(null, valid, messageKey, args); + return validateField(null, valid, messageKey, args); + } + + public MultiErrorException validateBean(String beanName, T bean) { + + Set> constraintViolations = + LexUtils.validator().validate(bean, validationGroups); + + addErrors(constraintViolations, beanName); + return this; } + /** + * Throws the exception, if there are accumulated errors + */ + public void go() { + if (!errors.isEmpty()) + throw this; + } + /** * Adds constraint violations * @@ -81,7 +113,7 @@ public MultiErrorException validate(boolean valid, * @param objectName * @return */ - public MultiErrorException addErrors(Set> constraintViolations, String objectName) { + private void addErrors(Set> constraintViolations, String objectName) { errors.addAll(constraintViolations.stream() .map(constraintViolation -> @@ -90,20 +122,5 @@ public MultiErrorException addErrors(Set> const constraintViolation.getMessageTemplate(), constraintViolation.getMessage())) .collect(Collectors.toList())); - - return this; - } - - /** - * Overrides the standard getMessage - */ - @Override - public String getMessage() { - - if (errors.isEmpty()) - return null; - - // return the first message - return errors.get(0).getMessage(); } } diff --git a/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/util/LexUtils.java b/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/util/LexUtils.java index b63fad24..0221915d 100644 --- a/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/util/LexUtils.java +++ b/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/util/LexUtils.java @@ -71,34 +71,34 @@ public static String getMessage(String messageKey, Object... args) { /** - * Validates the given object and throws ExplicitConstraintViolationException in case of errors + * Creates a MultiErrorException out of the given parameters */ - public static void validate(String objectName, T object, Class... groups) { + public static MultiErrorException validate( + boolean valid, String messageKey, Object... args) { - new MultiErrorException() - .exceptionId(getExceptionId(new ConstraintViolationException(null))) - .addErrors(validator.validate(object, groups), objectName) - .go(); + return validateField(null, valid, messageKey, args); } /** * Creates a MultiErrorException out of the given parameters */ - public static MultiErrorException validate( - boolean valid, String messageKey, Object... args) { + public static MultiErrorException validateField( + String fieldName, boolean valid, String messageKey, Object... args) { - return LexUtils.validate(null, valid, messageKey, args); + return new MultiErrorException().validateField(fieldName, valid, messageKey, args); } /** - * Creates a MultiErrorException out of the given parameters + * Creates a MultiErrorException out of the constraint violations in the given bean */ - public static MultiErrorException validate( - String fieldName, boolean valid, String messageKey, Object... args) { + public static MultiErrorException validateBean(String beanName, T bean, Class... validationGroups) { - return new MultiErrorException().validate(fieldName, valid, messageKey, args); + return new MultiErrorException() + .exceptionId(getExceptionId(new ConstraintViolationException(null))) + .validationGroups(validationGroups) + .validateBean(beanName, bean); } @@ -138,4 +138,9 @@ private static Throwable getRootException(Throwable ex) { return ex; } + + + public static LocalValidatorFactoryBean validator() { + return validator; + } } diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/LemonService.java b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/LemonService.java index adb0a473..6f42d8de 100644 --- a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/LemonService.java +++ b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/LemonService.java @@ -487,7 +487,7 @@ public String changePassword(U user, @Valid ChangePasswordForm changePasswordFor // checks LexUtils.ensureFound(user); - LexUtils.validate("changePasswordForm.oldPassword", + LexUtils.validateField("changePasswordForm.oldPassword", passwordEncoder.matches(changePasswordForm.getOldPassword(), oldPassword), "com.naturalprogrammer.spring.wrong.password").go(); @@ -552,7 +552,7 @@ public void requestEmailChange(U user, @Valid U updatedUser) { // checks LexUtils.ensureFound(user); - LexUtils.validate("updatedUser.password", + LexUtils.validateField("updatedUser.password", passwordEncoder.matches(updatedUser.getPassword(), user.getPassword()), "com.naturalprogrammer.spring.wrong.password").go(); diff --git a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveService.java b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveService.java index dd98858b..d4fdfdd0 100644 --- a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveService.java +++ b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveService.java @@ -504,7 +504,7 @@ protected U updateUser(U user, Optional currentUser, String patch) { log.debug("Updating user: " + user); U updatedUser = LecrUtils.applyPatch(user, patch); // create a patched form - LexUtils.validate("updatedUser", updatedUser, UserUtils.UpdateValidation.class); + LexUtils.validateBean("updatedUser", updatedUser, UserUtils.UpdateValidation.class).go(); LecmUtils.ensureCorrectVersion(user, updatedUser); updateUserFields(user, updatedUser, currentUser.get()); @@ -604,7 +604,7 @@ protected void changePassword(Tuple3 tuple) { String oldPassword = loggedIn.getPassword(); - LexUtils.validate("changePasswordForm.oldPassword", + LexUtils.validateField("changePasswordForm.oldPassword", passwordEncoder.matches(changePasswordForm.getOldPassword(), oldPassword), "com.naturalprogrammer.spring.wrong.password").go(); @@ -642,7 +642,7 @@ protected void requestEmailChange(Tuple3 tuple) { log.debug("Requesting email change: " + user); // checks - LexUtils.validate("emailFormMono.password", + LexUtils.validateField("emailFormMono.password", passwordEncoder.matches(emailForm.getPassword(), user.getPassword()), "com.naturalprogrammer.spring.wrong.password").go(); From 3fd2fd31ecf8c6317012ff57a25379ddd113152b Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Thu, 25 Oct 2018 08:33:00 +0530 Subject: [PATCH 072/116] Updated README --- README.md | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index c425d215..e8079678 100644 --- a/README.md +++ b/README.md @@ -4,21 +4,22 @@ When developing **real-world** Spring REST APIs and microservices, you face many challenges like -1. How to make the API truly _stateless_, using token authentication, session sliding etc. +1. How to follow a stateless and efficient security model – using JWT authentication, session sliding etc. 1. How to configure Spring Security to suit API development, e.g. returning _200_ or _401_ responses on login, configuring _CORS_, _JSON vulnerability protection_, etc. -1. How to handle _validations_ and _exceptions_ in a cross functional manner and send precise errors to the client. +1. How to elegantly do _validations_ and _exceptions_ and send precise errors to the client. +1. How to easily mix manual and bean validations in a single validation cycle. 1. How exactly to support multiple _social sign up/in_, using _OpenID Connect_ or _OAuth2_ providers such as _Google_ and _Facebook_. 1. How to code a robust user module (with features like _sign up_, _sign in_, _verify email_, _social sign up/in_, _update profile_, _forgot password_, _change password_, _change email_, _token authentication_ etc.) and share it across all your applications. -1. How to _secure microservices_ effeciently, using long-lived and short-lived JWTs. +1. How to correctly and effeciently _secure microservices_, using long-lived and short-lived JWTs. 1. What would be good ways to _test your API_. 1. How to do _Captcha validation_. 1. How to properly organize _application properties_. 1. How to use _PATCH_ and _JsonPatch_ to handle partial updates correctly. 1. How to do all the above reactively, using WebFlux and WebFlux security. -Coding all this rightly needs in-depth knowledge of Spring. It also takes a lot of development time and effort, and needs to be properly maintained as new versions of Spring modules come out. +Coding all this rightly needs in-depth knowledge of Spring. It also takes a lot of development time and effort, and needs to be properly maintained as new versions of Spring comes out. -**Spring Lemon** relieves you of all this burden. It's a set of configurable and extensible libraries, providing all above features. Use these to develop quality reactive or non-reactive monolith or microservices applications easily. +**Spring Lemon** relieves you of all this burden. It's a set of configurable and extensible libraries, providing all above features. Use these to develop quality reactive or non-reactive monolith or microservices applications quickly and easily. Even if you don't plan to use Spring Lemon, it's a good example to learn from, because it showcases the essential best practices for developing elegant web services and microservices using Spring. @@ -28,16 +29,16 @@ Read [this quick starter guide](https://github.com/naturalprogrammer/spring-lemo ## Libraries hierarchy -* **spring-lemon-exceptions**: Useful for elegant exception handling and validation in any Spring project - * **spring-lemon-commons**: Common for all things below - * **spring-lemon-commons-web**: For developing Spring Web (non-reactive) microservices - * **spring-lemon-commons-jpa**: For developing Spring Web (non-reactive) JPA microservices - * **spring-lemon-jpa**: For developing Spring Web (non-reactive) JPA monolith or auth-microservice - * **spring-lemon-commons-reactive**: For developing Spring WebFlux (reactive) microservices - * **spring-lemon-commons-mongo**: For developing Spring WebFlux (reactive) MongoDB microservices - * **spring-lemon-rective**: For developing Spring WebFlux (reactive) MongoDB monolith or auth-microservice +* [spring-lemon-exceptions](https://github.com/naturalprogrammer/spring-lemon/wiki/Spring-Lemon-Exceptions-Guide): Useful for elegant exception handling and validation in any Spring project + * [spring-lemon-commons](https://github.com/naturalprogrammer/spring-lemon/wiki/Spring-Lemon-Commons-Guide): Common for all things below + * [spring-lemon-commons-web](https://github.com/naturalprogrammer/spring-lemon/wiki/Spring-Lemon-Commons-Web-Guide): For developing Spring Web (non-reactive) microservices + * [spring-lemon-commons-jpa](https://github.com/naturalprogrammer/spring-lemon/wiki/Spring-Lemon-Commons-JPA-Guide): For developing Spring Web (non-reactive) JPA microservices + * [spring-lemon-jpa](https://github.com/naturalprogrammer/spring-lemon/wiki/Spring-Lemon-JPA-Guide): For developing Spring Web (non-reactive) JPA monolith or auth-microservice + * [spring-lemon-commons-reactive](https://github.com/naturalprogrammer/spring-lemon/wiki/Spring-Lemon-Commons-Reactive-Guide): For developing Spring WebFlux (reactive) microservices + * [spring-lemon-commons-mongo](https://github.com/naturalprogrammer/spring-lemon/wiki/Spring-Lemon-Commons-MongoDB-Guide): For developing Spring WebFlux (reactive) MongoDB microservices + * [spring-lemon-reactive](https://github.com/naturalprogrammer/spring-lemon/wiki/Spring-Lemon-Reactive-Guide): For developing Spring WebFlux (reactive) MongoDB monolith or auth-microservice -For example usage, see +For example usages, see * [Demo non-reactive monolith](https://github.com/naturalprogrammer/spring-lemon/tree/master/lemon-demo-jpa) * [Demo reactive monolith](https://github.com/naturalprogrammer/spring-lemon/tree/master/lemon-demo-reactive) @@ -52,6 +53,7 @@ For example usage, see 1. _Getting started guide_ 1. [Book](https://github.com/naturalprogrammer/spring-lemon/wiki/Getting-Started-With-Spring-Lemon) 1. [Video Tutorial](https://www.naturalprogrammer.com/p/spring-lemon-restful-web-services-development) +1. _[Official Documentation](https://github.com/naturalprogrammer/spring-lemon/wiki)_ 1. _Example applications_ * [Demo non-reactive monolith](https://github.com/naturalprogrammer/spring-lemon/tree/master/lemon-demo-jpa) * [Demo reactive monolith](https://github.com/naturalprogrammer/spring-lemon/tree/master/lemon-demo-reactive) From 272884b8dbeac0332ec533b00c8cea80ef15c9ae Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Sun, 11 Nov 2018 10:38:45 +0530 Subject: [PATCH 073/116] Updated version to 1.0.0.M9 --- lemon-demo-jpa/pom.xml | 2 +- lemon-demo-reactive/pom.xml | 2 +- pom.xml | 2 +- spring-lemon-commons-jpa/pom.xml | 2 +- spring-lemon-commons-mongo/pom.xml | 2 +- spring-lemon-commons-reactive/pom.xml | 2 +- spring-lemon-commons-web/pom.xml | 2 +- spring-lemon-commons/pom.xml | 2 +- spring-lemon-exceptions/pom.xml | 2 +- spring-lemon-jpa/pom.xml | 2 +- spring-lemon-reactive/pom.xml | 2 +- 11 files changed, 11 insertions(+), 11 deletions(-) diff --git a/lemon-demo-jpa/pom.xml b/lemon-demo-jpa/pom.xml index 7a337c0b..feee0969 100644 --- a/lemon-demo-jpa/pom.xml +++ b/lemon-demo-jpa/pom.xml @@ -14,7 +14,7 @@ com.naturalprogrammer spring-lemon - 1.0.0.M8 + 1.0.0.M9 diff --git a/lemon-demo-reactive/pom.xml b/lemon-demo-reactive/pom.xml index a18a44f0..b3410f7b 100644 --- a/lemon-demo-reactive/pom.xml +++ b/lemon-demo-reactive/pom.xml @@ -13,7 +13,7 @@ com.naturalprogrammer spring-lemon - 1.0.0.M8 + 1.0.0.M9 diff --git a/pom.xml b/pom.xml index e221118d..82377c7b 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.naturalprogrammer spring-lemon - 1.0.0.M8 + 1.0.0.M9 pom spring-lemon diff --git a/spring-lemon-commons-jpa/pom.xml b/spring-lemon-commons-jpa/pom.xml index 9a009e94..13a4d0ed 100644 --- a/spring-lemon-commons-jpa/pom.xml +++ b/spring-lemon-commons-jpa/pom.xml @@ -13,7 +13,7 @@ com.naturalprogrammer spring-lemon - 1.0.0.M8 + 1.0.0.M9 diff --git a/spring-lemon-commons-mongo/pom.xml b/spring-lemon-commons-mongo/pom.xml index 3c72890c..8ec4b49e 100644 --- a/spring-lemon-commons-mongo/pom.xml +++ b/spring-lemon-commons-mongo/pom.xml @@ -13,7 +13,7 @@ com.naturalprogrammer spring-lemon - 1.0.0.M8 + 1.0.0.M9 diff --git a/spring-lemon-commons-reactive/pom.xml b/spring-lemon-commons-reactive/pom.xml index f4771652..a045df3c 100644 --- a/spring-lemon-commons-reactive/pom.xml +++ b/spring-lemon-commons-reactive/pom.xml @@ -13,7 +13,7 @@ com.naturalprogrammer spring-lemon - 1.0.0.M8 + 1.0.0.M9 diff --git a/spring-lemon-commons-web/pom.xml b/spring-lemon-commons-web/pom.xml index ef30de83..2f96fb17 100644 --- a/spring-lemon-commons-web/pom.xml +++ b/spring-lemon-commons-web/pom.xml @@ -13,7 +13,7 @@ com.naturalprogrammer spring-lemon - 1.0.0.M8 + 1.0.0.M9 diff --git a/spring-lemon-commons/pom.xml b/spring-lemon-commons/pom.xml index 85d16092..da428087 100644 --- a/spring-lemon-commons/pom.xml +++ b/spring-lemon-commons/pom.xml @@ -14,7 +14,7 @@ com.naturalprogrammer spring-lemon - 1.0.0.M8 + 1.0.0.M9 diff --git a/spring-lemon-exceptions/pom.xml b/spring-lemon-exceptions/pom.xml index 698bdac7..316e0d7d 100644 --- a/spring-lemon-exceptions/pom.xml +++ b/spring-lemon-exceptions/pom.xml @@ -13,7 +13,7 @@ com.naturalprogrammer spring-lemon - 1.0.0.M8 + 1.0.0.M9 diff --git a/spring-lemon-jpa/pom.xml b/spring-lemon-jpa/pom.xml index 72615faa..bbd9a95e 100644 --- a/spring-lemon-jpa/pom.xml +++ b/spring-lemon-jpa/pom.xml @@ -13,7 +13,7 @@ com.naturalprogrammer spring-lemon - 1.0.0.M8 + 1.0.0.M9 diff --git a/spring-lemon-reactive/pom.xml b/spring-lemon-reactive/pom.xml index eab6f878..82040bfa 100644 --- a/spring-lemon-reactive/pom.xml +++ b/spring-lemon-reactive/pom.xml @@ -13,7 +13,7 @@ com.naturalprogrammer spring-lemon - 1.0.0.M8 + 1.0.0.M9 From 6efee4389cade60e42865ee40530f88ef6144e9d Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Sun, 11 Nov 2018 19:31:12 +0530 Subject: [PATCH 074/116] Added AuthTokenService, ExternalTokenService --- .../spring/lemondemo/ChangeEmailMvcTests.java | 18 +-- .../lemondemo/ResetPasswordMvcTests.java | 8 +- .../lemondemo/VerificationMvcTests.java | 12 +- .../spring/lemondemo/ChangeEmailTests.java | 18 +-- .../spring/lemondemo/ResetPasswordTests.java | 8 +- .../spring/lemondemo/VerificationTests.java | 12 +- ...LemonCommonsReactiveAutoConfiguration.java | 6 +- .../LemonCommonsReactiveSecurityConfig.java | 6 +- ...onCommonsWebTokenAuthenticationFilter.java | 15 +-- .../security/LemonWebSecurityConfig.java | 10 +- .../LemonCommonsAutoConfiguration.java | 26 +++- .../commons/security/AuthTokenService.java | 7 + .../security/ExternalTokenService.java | 8 ++ .../{JwtService.java => LemonJweService.java} | 57 ++++---- .../commons/security/LemonTokenService.java | 36 +++++ .../spring/lemon/commons/util/LecUtils.java | 4 +- .../commons/security/JwtServiceTests.java | 67 ---------- .../security/LemonJweServiceTests.java | 123 ++++++++++++++++++ .../spring/lemon/LemonAutoConfiguration.java | 6 +- .../spring/lemon/LemonController.java | 6 +- .../spring/lemon/LemonService.java | 47 ++++--- .../security/LemonJpaSecurityConfig.java | 3 +- .../LemonJpaTokenAuthenticationFilter.java | 6 +- .../OAuth2AuthenticationSuccessHandler.java | 19 +-- .../spring/lemon/util/LemonUtils.java | 4 +- .../LemonReactiveAutoConfiguration.java | 6 +- .../LemonReactiveController.java | 6 +- .../lemonreactive/LemonReactiveService.java | 42 +++--- .../security/LemonReactiveSecurityConfig.java | 6 +- .../spring/lemonreactive/util/LerUtils.java | 4 +- 30 files changed, 355 insertions(+), 241 deletions(-) create mode 100644 spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/AuthTokenService.java create mode 100644 spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/ExternalTokenService.java rename spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/{JwtService.java => LemonJweService.java} (78%) create mode 100644 spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/LemonTokenService.java delete mode 100644 spring-lemon-commons/src/test/java/com/naturalprogrammer/lemon/commons/security/JwtServiceTests.java create mode 100644 spring-lemon-commons/src/test/java/com/naturalprogrammer/lemon/commons/security/LemonJweServiceTests.java diff --git a/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/ChangeEmailMvcTests.java b/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/ChangeEmailMvcTests.java index 0bee2e3b..18aa018e 100644 --- a/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/ChangeEmailMvcTests.java +++ b/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/ChangeEmailMvcTests.java @@ -13,7 +13,7 @@ import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; -import com.naturalprogrammer.spring.lemon.commons.security.JwtService; +import com.naturalprogrammer.spring.lemon.commons.security.ExternalTokenService; import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; import com.naturalprogrammer.spring.lemondemo.entities.User; @@ -24,7 +24,7 @@ public class ChangeEmailMvcTests extends AbstractMvcTests { private String changeEmailCode; @Autowired - private JwtService jwtService; + private ExternalTokenService externalTokenService; @Before public void setUp() { @@ -33,8 +33,8 @@ public void setUp() { user.setNewEmail(NEW_EMAIL); userRepository.save(user); - changeEmailCode = jwtService.createToken( - JwtService.CHANGE_EMAIL_AUDIENCE, + changeEmailCode = externalTokenService.createToken( + ExternalTokenService.CHANGE_EMAIL_AUDIENCE, Long.toString(UNVERIFIED_USER_ID), 60000L, LecUtils.mapOf("newEmail", NEW_EMAIL)); } @@ -76,7 +76,7 @@ public void testChangeEmailWrongCode() throws Exception { .andExpect(status().is(422)); // Wrong audience - String code = jwtService.createToken( + String code = externalTokenService.createToken( "", // blank audience Long.toString(UNVERIFIED_USER_ID), 60000L, LecUtils.mapOf("newEmail", NEW_EMAIL)); @@ -88,8 +88,8 @@ public void testChangeEmailWrongCode() throws Exception { .andExpect(status().is(401)); // Wrong userId subject - code = jwtService.createToken( - JwtService.CHANGE_EMAIL_AUDIENCE, + code = externalTokenService.createToken( + ExternalTokenService.CHANGE_EMAIL_AUDIENCE, Long.toString(ADMIN_ID), 60000L, LecUtils.mapOf("newEmail", NEW_EMAIL)); @@ -100,8 +100,8 @@ public void testChangeEmailWrongCode() throws Exception { .andExpect(status().is(403)); // Wrong new email - code = jwtService.createToken( - JwtService.CHANGE_EMAIL_AUDIENCE, + code = externalTokenService.createToken( + ExternalTokenService.CHANGE_EMAIL_AUDIENCE, Long.toString(UNVERIFIED_USER_ID), 60000L, LecUtils.mapOf("newEmail", "wrong.new.email@example.com")); diff --git a/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/ResetPasswordMvcTests.java b/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/ResetPasswordMvcTests.java index d55d243f..9456b9c5 100644 --- a/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/ResetPasswordMvcTests.java +++ b/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/ResetPasswordMvcTests.java @@ -13,7 +13,7 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.naturalprogrammer.spring.lemon.commons.domain.ResetPasswordForm; -import com.naturalprogrammer.spring.lemon.commons.security.JwtService; +import com.naturalprogrammer.spring.lemon.commons.security.ExternalTokenService; import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; public class ResetPasswordMvcTests extends AbstractMvcTests { @@ -21,13 +21,13 @@ public class ResetPasswordMvcTests extends AbstractMvcTests { private String forgotPasswordCode; @Autowired - private JwtService jwtService; + private ExternalTokenService externalTokenService; @Before public void setUp() { - forgotPasswordCode = jwtService.createToken( - JwtService.FORGOT_PASSWORD_AUDIENCE, + forgotPasswordCode = externalTokenService.createToken( + ExternalTokenService.FORGOT_PASSWORD_AUDIENCE, ADMIN_EMAIL, 60000L); } diff --git a/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/VerificationMvcTests.java b/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/VerificationMvcTests.java index 7f9046ca..de24c54b 100644 --- a/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/VerificationMvcTests.java +++ b/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/VerificationMvcTests.java @@ -12,7 +12,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.MediaType; -import com.naturalprogrammer.spring.lemon.commons.security.JwtService; +import com.naturalprogrammer.spring.lemon.commons.security.ExternalTokenService; import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; import com.naturalprogrammer.spring.lemondemo.entities.User; @@ -21,12 +21,12 @@ public class VerificationMvcTests extends AbstractMvcTests { private String verificationCode; @Autowired - private JwtService jwtService; + private ExternalTokenService externalTokenService; @Before public void setUp() { - verificationCode = jwtService.createToken(JwtService.VERIFY_AUDIENCE, + verificationCode = externalTokenService.createToken(ExternalTokenService.VERIFY_AUDIENCE, Long.toString(UNVERIFIED_USER_ID), 60000L, LecUtils.mapOf("email", UNVERIFIED_USER_EMAIL)); } @@ -75,7 +75,7 @@ public void testEmailVerificationWrongToken() throws Exception { .andExpect(status().is(401)); // Wrong audience - String token = jwtService.createToken("wrong-audience", + String token = externalTokenService.createToken("wrong-audience", Long.toString(UNVERIFIED_USER_ID), 60000L, LecUtils.mapOf("email", UNVERIFIED_USER_EMAIL)); mvc.perform(post("/api/core/users/{userId}/verification", UNVERIFIED_USER_ID) @@ -84,7 +84,7 @@ public void testEmailVerificationWrongToken() throws Exception { .andExpect(status().is(401)); // Wrong email - token = jwtService.createToken(JwtService.VERIFY_AUDIENCE, + token = externalTokenService.createToken(ExternalTokenService.VERIFY_AUDIENCE, Long.toString(UNVERIFIED_USER_ID), 60000L, LecUtils.mapOf("email", "wrong.email@example.com")); mvc.perform(post("/api/core/users/{userId}/verification", UNVERIFIED_USER_ID) @@ -93,7 +93,7 @@ public void testEmailVerificationWrongToken() throws Exception { .andExpect(status().is(403)); // expired token - token = jwtService.createToken(JwtService.VERIFY_AUDIENCE, + token = externalTokenService.createToken(ExternalTokenService.VERIFY_AUDIENCE, Long.toString(UNVERIFIED_USER_ID), 1L, LecUtils.mapOf("email", UNVERIFIED_USER_EMAIL)); // Thread.sleep(1001L); diff --git a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/ChangeEmailTests.java b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/ChangeEmailTests.java index 63def41e..c0b58d23 100644 --- a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/ChangeEmailTests.java +++ b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/ChangeEmailTests.java @@ -18,7 +18,7 @@ import org.springframework.http.HttpStatus; import org.springframework.test.web.reactive.server.WebTestClient.ResponseSpec; -import com.naturalprogrammer.spring.lemon.commons.security.JwtService; +import com.naturalprogrammer.spring.lemon.commons.security.ExternalTokenService; import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; import com.naturalprogrammer.spring.lemondemo.domain.User; @@ -29,7 +29,7 @@ public class ChangeEmailTests extends AbstractTests { private String changeEmailCode; @Autowired - private JwtService jwtService; + private ExternalTokenService externalTokenService; @Before public void setUp() { @@ -38,8 +38,8 @@ public void setUp() { user.setNewEmail(NEW_EMAIL); mongoTemplate.save(user); - changeEmailCode = jwtService.createToken( - JwtService.CHANGE_EMAIL_AUDIENCE, + changeEmailCode = externalTokenService.createToken( + ExternalTokenService.CHANGE_EMAIL_AUDIENCE, UNVERIFIED_USER_ID.toString(), 60000L, LecUtils.mapOf("newEmail", NEW_EMAIL)); } @@ -71,7 +71,7 @@ public void testChangeEmailWrongCode() throws Exception { .expectStatus().isEqualTo(HttpStatus.UNPROCESSABLE_ENTITY); // Wrong audience - String code = jwtService.createToken( + String code = externalTokenService.createToken( "", // blank audience UNVERIFIED_USER_ID.toString(), 60000L, LecUtils.mapOf("newEmail", NEW_EMAIL)); @@ -80,8 +80,8 @@ public void testChangeEmailWrongCode() throws Exception { .expectStatus().isUnauthorized(); // Wrong userId subject - code = jwtService.createToken( - JwtService.CHANGE_EMAIL_AUDIENCE, + code = externalTokenService.createToken( + ExternalTokenService.CHANGE_EMAIL_AUDIENCE, ADMIN_ID.toString(), 60000L, LecUtils.mapOf("newEmail", NEW_EMAIL)); @@ -89,8 +89,8 @@ public void testChangeEmailWrongCode() throws Exception { .expectStatus().isForbidden(); // Wrong new email - code = jwtService.createToken( - JwtService.CHANGE_EMAIL_AUDIENCE, + code = externalTokenService.createToken( + ExternalTokenService.CHANGE_EMAIL_AUDIENCE, UNVERIFIED_USER_ID.toString(), 60000L, LecUtils.mapOf("newEmail", "wrong.new.email@example.com")); diff --git a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/ResetPasswordTests.java b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/ResetPasswordTests.java index 6782758a..d49c64f8 100644 --- a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/ResetPasswordTests.java +++ b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/ResetPasswordTests.java @@ -12,7 +12,7 @@ import org.springframework.http.MediaType; import org.springframework.test.web.reactive.server.WebTestClient.ResponseSpec; -import com.naturalprogrammer.spring.lemon.commons.security.JwtService; +import com.naturalprogrammer.spring.lemon.commons.security.ExternalTokenService; import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; import com.naturalprogrammer.spring.lemondemo.dto.TestResetPasswordForm; @@ -23,13 +23,13 @@ public class ResetPasswordTests extends AbstractTests { private String forgotPasswordCode; @Autowired - private JwtService jwtService; + private ExternalTokenService externalTokenService; @Before public void setUp() { - forgotPasswordCode = jwtService.createToken( - JwtService.FORGOT_PASSWORD_AUDIENCE, + forgotPasswordCode = externalTokenService.createToken( + ExternalTokenService.FORGOT_PASSWORD_AUDIENCE, ADMIN_EMAIL, 60000L); } diff --git a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/VerificationTests.java b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/VerificationTests.java index 4f4faa41..4bd5e25b 100644 --- a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/VerificationTests.java +++ b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/VerificationTests.java @@ -16,7 +16,7 @@ import org.springframework.http.HttpStatus; import org.springframework.test.web.reactive.server.WebTestClient.ResponseSpec; -import com.naturalprogrammer.spring.lemon.commons.security.JwtService; +import com.naturalprogrammer.spring.lemon.commons.security.ExternalTokenService; import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; import com.naturalprogrammer.spring.lemondemo.dto.TestUserDto; @@ -25,12 +25,12 @@ public class VerificationTests extends AbstractTests { private String verificationCode; @Autowired - private JwtService jwtService; + private ExternalTokenService externalTokenService; @Before public void setUp() { - verificationCode = jwtService.createToken(JwtService.VERIFY_AUDIENCE, + verificationCode = externalTokenService.createToken(ExternalTokenService.VERIFY_AUDIENCE, UNVERIFIED_USER_ID.toString(), 60000L, LecUtils.mapOf("email", UNVERIFIED_USER_EMAIL)); } @@ -77,21 +77,21 @@ public void testEmailVerificationWrongToken() throws Exception { .expectStatus().isEqualTo(HttpStatus.UNPROCESSABLE_ENTITY); // Wrong audience - String token = jwtService.createToken("wrong-audience", + String token = externalTokenService.createToken("wrong-audience", UNVERIFIED_USER_ID.toString(), 60000L, LecUtils.mapOf("email", UNVERIFIED_USER_EMAIL)); emailVerification(UNVERIFIED_USER_ID, token) .expectStatus().isUnauthorized(); // Wrong email - token = jwtService.createToken(JwtService.VERIFY_AUDIENCE, + token = externalTokenService.createToken(ExternalTokenService.VERIFY_AUDIENCE, UNVERIFIED_USER_ID.toString(), 60000L, LecUtils.mapOf("email", "wrong.email@example.com")); emailVerification(UNVERIFIED_USER_ID, token) .expectStatus().isForbidden(); // expired token - token = jwtService.createToken(JwtService.VERIFY_AUDIENCE, + token = externalTokenService.createToken(ExternalTokenService.VERIFY_AUDIENCE, UNVERIFIED_USER_ID.toString(), 1L, LecUtils.mapOf("email", UNVERIFIED_USER_EMAIL)); emailVerification(UNVERIFIED_USER_ID, token) diff --git a/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/LemonCommonsReactiveAutoConfiguration.java b/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/LemonCommonsReactiveAutoConfiguration.java index 507cdf11..63c05677 100644 --- a/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/LemonCommonsReactiveAutoConfiguration.java +++ b/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/LemonCommonsReactiveAutoConfiguration.java @@ -26,7 +26,7 @@ import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; import com.naturalprogrammer.spring.lemon.commons.LemonCommonsAutoConfiguration; import com.naturalprogrammer.spring.lemon.commons.LemonProperties; -import com.naturalprogrammer.spring.lemon.commons.security.JwtService; +import com.naturalprogrammer.spring.lemon.commons.security.AuthTokenService; import com.naturalprogrammer.spring.lemon.commonsreactive.exceptions.LemonReactiveErrorAttributes; import com.naturalprogrammer.spring.lemon.commonsreactive.exceptions.handlers.VersionExceptionHandler; import com.naturalprogrammer.spring.lemon.commonsreactive.security.LemonCommonsReactiveSecurityConfig; @@ -68,10 +68,10 @@ ErrorAttributes errorAttributes(ErrorResponseComposer errorResponseComposer) @Bean @ConditionalOnMissingBean(LemonCommonsReactiveSecurityConfig.class) - public LemonCommonsReactiveSecurityConfig lemonReactiveSecurityConfig(JwtService jwtService) { + public LemonCommonsReactiveSecurityConfig lemonReactiveSecurityConfig(AuthTokenService authTokenService) { log.info("Configuring LemonCommonsReactiveSecurityConfig ..."); - return new LemonCommonsReactiveSecurityConfig(jwtService); + return new LemonCommonsReactiveSecurityConfig(authTokenService); } diff --git a/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/security/LemonCommonsReactiveSecurityConfig.java b/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/security/LemonCommonsReactiveSecurityConfig.java index 573451a3..07df4af6 100644 --- a/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/security/LemonCommonsReactiveSecurityConfig.java +++ b/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/security/LemonCommonsReactiveSecurityConfig.java @@ -19,7 +19,7 @@ import org.springframework.security.web.server.context.NoOpServerSecurityContextRepository; import org.springframework.web.server.ServerWebExchange; -import com.naturalprogrammer.spring.lemon.commons.security.JwtService; +import com.naturalprogrammer.spring.lemon.commons.security.AuthTokenService; import com.naturalprogrammer.spring.lemon.commons.security.LemonPrincipal; import com.naturalprogrammer.spring.lemon.commons.security.UserDto; import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; @@ -34,7 +34,7 @@ public class LemonCommonsReactiveSecurityConfig { private static final Log log = LogFactory.getLog(LemonCommonsReactiveSecurityConfig.class); - protected JwtService jwtService; + protected AuthTokenService authTokenService; public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) { @@ -91,7 +91,7 @@ protected ReactiveAuthenticationManager tokenAuthenticationManager() { String token = (String) authentication.getCredentials(); - JWTClaimsSet claims = jwtService.parseToken(token, JwtService.AUTH_AUDIENCE); + JWTClaimsSet claims = authTokenService.parseToken(token, AuthTokenService.AUTH_AUDIENCE); UserDto userDto = LecUtils.getUserDto(claims); diff --git a/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/security/LemonCommonsWebTokenAuthenticationFilter.java b/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/security/LemonCommonsWebTokenAuthenticationFilter.java index 11ccccda..033781f4 100644 --- a/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/security/LemonCommonsWebTokenAuthenticationFilter.java +++ b/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/security/LemonCommonsWebTokenAuthenticationFilter.java @@ -16,27 +16,24 @@ import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.web.filter.OncePerRequestFilter; -import com.naturalprogrammer.spring.lemon.commons.security.JwtService; +import com.naturalprogrammer.spring.lemon.commons.security.AuthTokenService; import com.naturalprogrammer.spring.lemon.commons.security.LemonPrincipal; import com.naturalprogrammer.spring.lemon.commons.security.UserDto; import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; import com.naturalprogrammer.spring.lemon.exceptions.util.LexUtils; import com.nimbusds.jwt.JWTClaimsSet; +import lombok.AllArgsConstructor; + /** * Filter for token authentication */ +@AllArgsConstructor public class LemonCommonsWebTokenAuthenticationFilter extends OncePerRequestFilter { private static final Log log = LogFactory.getLog(LemonCommonsWebTokenAuthenticationFilter.class); - private JwtService jwtService; - - public LemonCommonsWebTokenAuthenticationFilter(JwtService jwtService) { - - this.jwtService = jwtService; - log.info("Created"); - } + private AuthTokenService authTokenService; @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) @@ -77,7 +74,7 @@ protected void doFilterInternal(HttpServletRequest request, HttpServletResponse protected Authentication createAuthToken(String token) { - JWTClaimsSet claims = jwtService.parseToken(token, JwtService.AUTH_AUDIENCE); + JWTClaimsSet claims = authTokenService.parseToken(token, AuthTokenService.AUTH_AUDIENCE); UserDto userDto = LecUtils.getUserDto(claims); if (userDto == null) userDto = fetchUserDto(claims); diff --git a/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/security/LemonWebSecurityConfig.java b/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/security/LemonWebSecurityConfig.java index fbad3a0b..027fb017 100644 --- a/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/security/LemonWebSecurityConfig.java +++ b/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/security/LemonWebSecurityConfig.java @@ -9,7 +9,7 @@ import org.springframework.security.web.authentication.Http403ForbiddenEntryPoint; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; -import com.naturalprogrammer.spring.lemon.commons.security.JwtService; +import com.naturalprogrammer.spring.lemon.commons.security.AuthTokenService; /** * Security configuration class. Extend it in the @@ -22,12 +22,12 @@ public class LemonWebSecurityConfig extends WebSecurityConfigurerAdapter { private static final Log log = LogFactory.getLog(LemonWebSecurityConfig.class); - protected JwtService jwtService; + protected AuthTokenService authTokenService; @Autowired - public void createLemonWebSecurityConfig(JwtService jwtService) { + public void createLemonWebSecurityConfig(AuthTokenService authTokenService) { - this.jwtService = jwtService; + this.authTokenService = authTokenService; log.info("Created"); } @@ -90,7 +90,7 @@ protected void exceptionHandling(HttpSecurity http) throws Exception { */ protected void tokenAuthentication(HttpSecurity http) throws Exception { - http.addFilterBefore(new LemonCommonsWebTokenAuthenticationFilter(jwtService), + http.addFilterBefore(new LemonCommonsWebTokenAuthenticationFilter(authTokenService), UsernamePasswordAuthenticationFilter.class); } diff --git a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/LemonCommonsAutoConfiguration.java b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/LemonCommonsAutoConfiguration.java index 8c4e39d2..2d8269c3 100644 --- a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/LemonCommonsAutoConfiguration.java +++ b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/LemonCommonsAutoConfiguration.java @@ -21,7 +21,9 @@ import com.naturalprogrammer.spring.lemon.commons.mail.MailSender; import com.naturalprogrammer.spring.lemon.commons.mail.MockMailSender; import com.naturalprogrammer.spring.lemon.commons.mail.SmtpMailSender; -import com.naturalprogrammer.spring.lemon.commons.security.JwtService; +import com.naturalprogrammer.spring.lemon.commons.security.AuthTokenService; +import com.naturalprogrammer.spring.lemon.commons.security.ExternalTokenService; +import com.naturalprogrammer.spring.lemon.commons.security.LemonJweService; import com.naturalprogrammer.spring.lemon.commons.security.LemonPermissionEvaluator; import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; import com.naturalprogrammer.spring.lemon.commons.validation.CaptchaValidator; @@ -54,14 +56,26 @@ public LemonProperties lemonProperties() { /** - * Configures JwtService if missing + * Configures AuthTokenService if missing */ @Bean - @ConditionalOnMissingBean(JwtService.class) - public JwtService jwtService(LemonProperties properties) throws KeyLengthException { + @ConditionalOnMissingBean(AuthTokenService.class) + public AuthTokenService authTokenService(LemonProperties properties) throws KeyLengthException { - log.info("Configuring AuthenticationSuccessHandler"); - return new JwtService(properties.getJwt().getSecret()); + log.info("Configuring AuthTokenService"); + return new LemonJweService(properties.getJwt().getSecret()); + } + + + /** + * Configures AuthTokenService if missing + */ + @Bean + @ConditionalOnMissingBean(ExternalTokenService.class) + public ExternalTokenService externalTokenService(LemonProperties properties) throws KeyLengthException { + + log.info("Configuring ExternalTokenService"); + return new LemonJweService(properties.getJwt().getSecret()); } diff --git a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/AuthTokenService.java b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/AuthTokenService.java new file mode 100644 index 00000000..9fcaaaff --- /dev/null +++ b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/AuthTokenService.java @@ -0,0 +1,7 @@ +package com.naturalprogrammer.spring.lemon.commons.security; + +public interface AuthTokenService extends LemonTokenService { + + String USER_CLAIM = "user"; + String AUTH_AUDIENCE = "auth"; +} diff --git a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/ExternalTokenService.java b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/ExternalTokenService.java new file mode 100644 index 00000000..b82ae6ec --- /dev/null +++ b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/ExternalTokenService.java @@ -0,0 +1,8 @@ +package com.naturalprogrammer.spring.lemon.commons.security; + +public interface ExternalTokenService extends LemonTokenService { + + String VERIFY_AUDIENCE = "verify"; + String FORGOT_PASSWORD_AUDIENCE = "forgot-password"; + String CHANGE_EMAIL_AUDIENCE = "change-email"; +} diff --git a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/JwtService.java b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/LemonJweService.java similarity index 78% rename from spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/JwtService.java rename to spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/LemonJweService.java index 7a71f54c..2dfc6584 100644 --- a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/JwtService.java +++ b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/LemonJweService.java @@ -36,23 +36,15 @@ * https://connect2id.com/products/nimbus-jose-jwt/examples/jwe-with-shared-key * https://connect2id.com/products/nimbus-jose-jwt/examples/validating-jwt-access-tokens */ -public class JwtService { +public class LemonJweService implements AuthTokenService, ExternalTokenService { - private static final Log log = LogFactory.getLog(JwtService.class); + private static final Log log = LogFactory.getLog(LemonJweService.class); - public static final String LEMON_IAT = "lemon-iat"; - public static final String USER_CLAIM = "user"; - - public static final String AUTH_AUDIENCE = "auth"; - public static final String VERIFY_AUDIENCE = "verify"; - public static final String FORGOT_PASSWORD_AUDIENCE = "forgot-password"; - public static final String CHANGE_EMAIL_AUDIENCE = "change-email"; - - private DirectEncrypter encrypter; + private DirectEncrypter encrypter; private JWEHeader header = new JWEHeader(JWEAlgorithm.DIR, EncryptionMethod.A128CBC_HS256); private ConfigurableJWTProcessor jwtProcessor; - public JwtService(String secret) throws KeyLengthException { + public LemonJweService(String secret) throws KeyLengthException { byte[] secretKey = secret.getBytes(); encrypter = new DirectEncrypter(secretKey); @@ -68,9 +60,10 @@ public JwtService(String secret) throws KeyLengthException { jwtProcessor.setJWEKeySelector(jweKeySelector); } - /** - * Creates a token + /* (non-Javadoc) + * @see com.naturalprogrammer.spring.lemon.commons.security.JwtService#createToken(java.lang.String, java.lang.String, java.lang.Long, java.util.Map) */ + @Override public String createToken(String aud, String subject, Long expirationMillis, Map claimMap) { JWTClaimsSet.Builder builder = new JWTClaimsSet.Builder(); @@ -105,17 +98,19 @@ public String createToken(String aud, String subject, Long expirationMillis, Map return jweObject.serialize(); } - /** - * Creates a token + /* (non-Javadoc) + * @see com.naturalprogrammer.spring.lemon.commons.security.JwtService#createToken(java.lang.String, java.lang.String, java.lang.Long) */ + @Override public String createToken(String audience, String subject, Long expirationMillis) { return createToken(audience, subject, expirationMillis, new HashMap<>()); } - /** - * Parses a token + /* (non-Javadoc) + * @see com.naturalprogrammer.spring.lemon.commons.security.JwtService#parseToken(java.lang.String, java.lang.String) */ + @Override public JWTClaimsSet parseToken(String token, String audience) { JWTClaimsSet claims = parseToken(token); @@ -135,9 +130,10 @@ public JWTClaimsSet parseToken(String token, String audience) { return claims; } - /** - * Parses a token + /* (non-Javadoc) + * @see com.naturalprogrammer.spring.lemon.commons.security.JwtService#parseToken(java.lang.String, java.lang.String, long) */ + @Override public JWTClaimsSet parseToken(String token, String audience, long issuedAfter) { JWTClaimsSet claims = parseToken(token, audience); @@ -149,10 +145,20 @@ public JWTClaimsSet parseToken(String token, String audience, long issuedAfter) return claims; } + /* (non-Javadoc) + * @see com.naturalprogrammer.spring.lemon.commons.security.JwtService#parseClaim(java.lang.String, java.lang.String) + */ + @Override + public T parseClaim(String token, String claim) { + + JWTClaimsSet claims = parseToken(token); + return (T) claims.getClaim(claim); + } + /** * Parses a token */ - public JWTClaimsSet parseToken(String token) { + protected JWTClaimsSet parseToken(String token) { try { @@ -163,13 +169,4 @@ public JWTClaimsSet parseToken(String token) { throw new BadCredentialsException(e.getMessage()); } } - - /** - * Parses a claim - */ - public T parseClaim(String token, String claim) { - - JWTClaimsSet claims = parseToken(token); - return (T) claims.getClaim(claim); - } } diff --git a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/LemonTokenService.java b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/LemonTokenService.java new file mode 100644 index 00000000..964d1481 --- /dev/null +++ b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/LemonTokenService.java @@ -0,0 +1,36 @@ +package com.naturalprogrammer.spring.lemon.commons.security; + +import java.util.Map; + +import com.nimbusds.jwt.JWTClaimsSet; + +public interface LemonTokenService { + + String LEMON_IAT = "lemon-iat"; + + /** + * Creates a token + */ + String createToken(String aud, String subject, Long expirationMillis, Map claimMap); + + /** + * Creates a token + */ + String createToken(String audience, String subject, Long expirationMillis); + + /** + * Parses a token + */ + JWTClaimsSet parseToken(String token, String audience); + + /** + * Parses a token + */ + JWTClaimsSet parseToken(String token, String audience, long issuedAfter); + + /** + * Parses a claim + */ + T parseClaim(String token, String claim); + +} \ No newline at end of file diff --git a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/util/LecUtils.java b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/util/LecUtils.java index 3d4ad601..35ee010f 100644 --- a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/util/LecUtils.java +++ b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/util/LecUtils.java @@ -25,7 +25,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.github.fge.jsonpatch.JsonPatch; import com.github.fge.jsonpatch.JsonPatchException; -import com.naturalprogrammer.spring.lemon.commons.security.JwtService; +import com.naturalprogrammer.spring.lemon.commons.security.AuthTokenService; import com.naturalprogrammer.spring.lemon.commons.security.LemonPrincipal; import com.naturalprogrammer.spring.lemon.commons.security.UserDto; import com.naturalprogrammer.spring.lemon.exceptions.util.LexUtils; @@ -255,7 +255,7 @@ public static T deserialize(String serializedObj) { public static UserDto getUserDto(JWTClaimsSet claims) { - Object userClaim = claims.getClaim(JwtService.USER_CLAIM); + Object userClaim = claims.getClaim(AuthTokenService.USER_CLAIM); if (userClaim == null) return null; diff --git a/spring-lemon-commons/src/test/java/com/naturalprogrammer/lemon/commons/security/JwtServiceTests.java b/spring-lemon-commons/src/test/java/com/naturalprogrammer/lemon/commons/security/JwtServiceTests.java deleted file mode 100644 index a2d46853..00000000 --- a/spring-lemon-commons/src/test/java/com/naturalprogrammer/lemon/commons/security/JwtServiceTests.java +++ /dev/null @@ -1,67 +0,0 @@ -package com.naturalprogrammer.lemon.commons.security; - -import org.junit.Assert; -import org.junit.Test; -import org.springframework.security.authentication.BadCredentialsException; - -import com.naturalprogrammer.spring.lemon.commons.security.JwtService; -import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; -import com.nimbusds.jose.KeyLengthException; -import com.nimbusds.jwt.JWTClaimsSet; - -public class JwtServiceTests { - - // An aes-128-cbc key generated at https://asecuritysite.com/encryption/keygen (take the "key" field) - private static final String SECRET1 = "926D96C90030DD58429D2751AC1BDBBC"; - private static final String SECRET2 = "538518AB685B514685DA8055C03DDA63"; - - private JwtService service1; - private JwtService service2; - - public JwtServiceTests() throws KeyLengthException { - - service1 = new JwtService(SECRET1); - service2 = new JwtService(SECRET2); - } - - @Test - public void testJwtParseToken() { - - String token = service1.createToken("auth", "subject", 5000L, - LecUtils.mapOf("username", "abc@example.com")); - JWTClaimsSet claims = service1.parseToken(token, "auth"); - - Assert.assertEquals("subject", claims.getSubject()); - Assert.assertEquals("abc@example.com", claims.getClaim("username")); - } - - @Test(expected = BadCredentialsException.class) - public void testJwtParseTokenWrongAudience() { - - String token = service1.createToken("auth", "subject", 5000L); - service1.parseToken(token, "auth2"); - } - - @Test(expected = BadCredentialsException.class) - public void testJwtParseTokenExpired() throws InterruptedException { - - String token = service1.createToken("auth", "subject", 1L); - Thread.sleep(1L); - service1.parseToken(token, "auth"); - } - - @Test(expected = BadCredentialsException.class) - public void testJwtParseTokenWrongSecret() { - - String token = service1.createToken("auth", "subject", 5000L); - service2.parseToken(token, "auth"); - } - - @Test(expected = BadCredentialsException.class) - public void testParseTokenCutoffTime() throws InterruptedException { - - String token = service1.createToken("auth", "subject", 5000L); - Thread.sleep(1L); - service1.parseToken(token, "auth", System.currentTimeMillis()); - } -} diff --git a/spring-lemon-commons/src/test/java/com/naturalprogrammer/lemon/commons/security/LemonJweServiceTests.java b/spring-lemon-commons/src/test/java/com/naturalprogrammer/lemon/commons/security/LemonJweServiceTests.java new file mode 100644 index 00000000..1cb9f8c9 --- /dev/null +++ b/spring-lemon-commons/src/test/java/com/naturalprogrammer/lemon/commons/security/LemonJweServiceTests.java @@ -0,0 +1,123 @@ +package com.naturalprogrammer.lemon.commons.security; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.security.SecureRandom; +import java.text.ParseException; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.junit.Assert; +import org.junit.Test; +import org.springframework.security.authentication.BadCredentialsException; + +import com.naturalprogrammer.spring.lemon.commons.security.LemonJweService; +import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; +import com.nimbusds.jose.JOSEException; +import com.nimbusds.jose.JWSAlgorithm; +import com.nimbusds.jose.JWSHeader; +import com.nimbusds.jose.JWSObject; +import com.nimbusds.jose.JWSSigner; +import com.nimbusds.jose.JWSVerifier; +import com.nimbusds.jose.KeyLengthException; +import com.nimbusds.jose.Payload; +import com.nimbusds.jose.crypto.MACSigner; +import com.nimbusds.jose.crypto.MACVerifier; +import com.nimbusds.jwt.JWTClaimsSet; + +public class LemonJweServiceTests { + + private static final Log log = LogFactory.getLog(LemonJweServiceTests.class); + + // An aes-128-cbc key generated at https://asecuritysite.com/encryption/keygen (take the "key" field) + private static final String SECRET1 = "926D96C90030DD58429D2751AC1BDBBC"; + private static final String SECRET2 = "538518AB685B514685DA8055C03DDA63"; + + private LemonJweService service1; + private LemonJweService service2; + + public LemonJweServiceTests() throws KeyLengthException { + + service1 = new LemonJweService(SECRET1); + service2 = new LemonJweService(SECRET2); + } + + @Test + public void testJwtParseToken() { + + log.info("Creating token ..."); + String token = service1.createToken("auth", "subject", 5000L, + LecUtils.mapOf("username", "abc@example.com")); + + log.info("Parsing token ..."); + JWTClaimsSet claims = service1.parseToken(token, "auth"); + + log.info("Parsed token."); + Assert.assertEquals("subject", claims.getSubject()); + Assert.assertEquals("abc@example.com", claims.getClaim("username")); + } + + @Test + public void testJws() throws KeyLengthException, JOSEException, ParseException { + + // We need a 256-bit key for HS256 which must be pre-shared + byte[] sharedKey = new byte[32]; + new SecureRandom().nextBytes(sharedKey); + + JWSSigner signer = new MACSigner(sharedKey); + JWSVerifier verifier = new MACVerifier(sharedKey); + + + log.info("Creating JWS token ..."); + // Create an HMAC-protected JWS object with some payload + JWSObject jwsObject = new JWSObject(new JWSHeader(JWSAlgorithm.HS256), + new Payload("Hello, world!")); + + // Apply the HMAC to the JWS object + jwsObject.sign(signer); + + String token = jwsObject.serialize(); + + // Output in URL-safe format + log.info("Created token: " + token); + + // To parse the JWS and verify it, e.g. on client-side + jwsObject = JWSObject.parse(token); + assertTrue(jwsObject.verify(verifier)); + assertEquals("Hello, world!", jwsObject.getPayload().toString()); + log.info("Parsed token."); + + + } + + @Test(expected = BadCredentialsException.class) + public void testJwtParseTokenWrongAudience() { + + String token = service1.createToken("auth", "subject", 5000L); + service1.parseToken(token, "auth2"); + } + + @Test(expected = BadCredentialsException.class) + public void testJwtParseTokenExpired() throws InterruptedException { + + String token = service1.createToken("auth", "subject", 1L); + Thread.sleep(1L); + service1.parseToken(token, "auth"); + } + + @Test(expected = BadCredentialsException.class) + public void testJwtParseTokenWrongSecret() { + + String token = service1.createToken("auth", "subject", 5000L); + service2.parseToken(token, "auth"); + } + + @Test(expected = BadCredentialsException.class) + public void testParseTokenCutoffTime() throws InterruptedException { + + String token = service1.createToken("auth", "subject", 5000L); + Thread.sleep(1L); + service1.parseToken(token, "auth", System.currentTimeMillis()); + } +} diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/LemonAutoConfiguration.java b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/LemonAutoConfiguration.java index cac71cef..156d069d 100644 --- a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/LemonAutoConfiguration.java +++ b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/LemonAutoConfiguration.java @@ -19,7 +19,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.naturalprogrammer.spring.lemon.commons.LemonProperties; import com.naturalprogrammer.spring.lemon.commons.domain.IdConverter; -import com.naturalprogrammer.spring.lemon.commons.security.JwtService; +import com.naturalprogrammer.spring.lemon.commons.security.AuthTokenService; import com.naturalprogrammer.spring.lemon.commons.validation.RetypePasswordValidator; import com.naturalprogrammer.spring.lemon.commonsjpa.LemonCommonsJpaAutoConfiguration; import com.naturalprogrammer.spring.lemon.commonsweb.security.LemonWebSecurityConfig; @@ -77,10 +77,10 @@ public LemonAuthenticationSuccessHandler authenticationSuccessHandler( @Bean @ConditionalOnMissingBean(OAuth2AuthenticationSuccessHandler.class) public OAuth2AuthenticationSuccessHandler oauth2AuthenticationSuccessHandler( - LemonProperties properties, JwtService jwtService) { + LemonProperties properties, AuthTokenService authTokenService) { log.info("Configuring OAuth2AuthenticationSuccessHandler"); - return new OAuth2AuthenticationSuccessHandler<>(properties, jwtService); + return new OAuth2AuthenticationSuccessHandler<>(properties, authTokenService); } /** diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/LemonController.java b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/LemonController.java index b2cfc43b..5a9fbc18 100644 --- a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/LemonController.java +++ b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/LemonController.java @@ -27,7 +27,6 @@ import com.naturalprogrammer.spring.lemon.commons.LemonProperties; import com.naturalprogrammer.spring.lemon.commons.domain.ChangePasswordForm; import com.naturalprogrammer.spring.lemon.commons.domain.ResetPasswordForm; -import com.naturalprogrammer.spring.lemon.commons.security.JwtService; import com.naturalprogrammer.spring.lemon.commons.security.UserDto; import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; import com.naturalprogrammer.spring.lemon.commons.util.UserUtils; @@ -48,18 +47,15 @@ public abstract class LemonController private static final Log log = LogFactory.getLog(LemonController.class); private long jwtExpirationMillis; - private JwtService jwtService; private LemonService lemonService; @Autowired public void createLemonController( LemonProperties properties, - LemonService lemonService, - JwtService jwtService) { + LemonService lemonService) { this.jwtExpirationMillis = properties.getJwt().getExpirationMillis(); this.lemonService = lemonService; - this.jwtService = jwtService; log.info("Created"); } diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/LemonService.java b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/LemonService.java index 6f42d8de..2368b1c3 100644 --- a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/LemonService.java +++ b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/LemonService.java @@ -33,7 +33,8 @@ import com.naturalprogrammer.spring.lemon.commons.domain.ResetPasswordForm; import com.naturalprogrammer.spring.lemon.commons.mail.LemonMailData; import com.naturalprogrammer.spring.lemon.commons.mail.MailSender; -import com.naturalprogrammer.spring.lemon.commons.security.JwtService; +import com.naturalprogrammer.spring.lemon.commons.security.AuthTokenService; +import com.naturalprogrammer.spring.lemon.commons.security.ExternalTokenService; import com.naturalprogrammer.spring.lemon.commons.security.UserDto; import com.naturalprogrammer.spring.lemon.commons.security.UserEditPermission; import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; @@ -63,7 +64,8 @@ public abstract class LemonService private MailSender mailSender; private AbstractUserRepository userRepository; private UserDetailsService userDetailsService; - private JwtService jwtService; + private AuthTokenService authTokenService; + private ExternalTokenService externalTokenService; @Autowired public void createLemonService(LemonProperties properties, @@ -71,14 +73,16 @@ public void createLemonService(LemonProperties properties, MailSender mailSender, AbstractUserRepository userRepository, UserDetailsService userDetailsService, - JwtService jwtService) { + AuthTokenService authTokenService, + ExternalTokenService externalTokenService) { this.properties = properties; this.passwordEncoder = passwordEncoder; this.mailSender = mailSender; this.userRepository = userRepository; this.userDetailsService = userDetailsService; - this.jwtService = jwtService; + this.authTokenService = authTokenService; + this.externalTokenService = externalTokenService; log.info("Created"); } @@ -243,7 +247,8 @@ protected void sendVerificationMail(final U user) { log.debug("Sending verification mail to: " + user); - String verificationCode = jwtService.createToken(JwtService.VERIFY_AUDIENCE, + String verificationCode = externalTokenService.createToken( + ExternalTokenService.VERIFY_AUDIENCE, user.getId().toString(), properties.getJwt().getExpirationMillis(), LecUtils.mapOf("email", user.getEmail())); @@ -336,7 +341,8 @@ public void verifyUser(ID userId, String verificationCode) { LexUtils.validate(user.hasRole(UserUtils.Role.UNVERIFIED), "com.naturalprogrammer.spring.alreadyVerified").go(); - JWTClaimsSet claims = jwtService.parseToken(verificationCode, JwtService.VERIFY_AUDIENCE, user.getCredentialsUpdatedMillis()); + JWTClaimsSet claims = externalTokenService.parseToken(verificationCode, + ExternalTokenService.VERIFY_AUDIENCE, user.getCredentialsUpdatedMillis()); LecUtils.ensureAuthority( claims.getSubject().equals(user.getId().toString()) && @@ -384,7 +390,8 @@ public void mailForgotPasswordLink(U user) { log.debug("Mailing forgot password link to user: " + user); - String forgotPasswordCode = jwtService.createToken(JwtService.FORGOT_PASSWORD_AUDIENCE, + String forgotPasswordCode = externalTokenService.createToken( + ExternalTokenService.FORGOT_PASSWORD_AUDIENCE, user.getEmail(), properties.getJwt().getExpirationMillis()); // make the link @@ -419,8 +426,8 @@ public void resetPassword(@Valid ResetPasswordForm form) { log.debug("Resetting password ..."); - JWTClaimsSet claims = jwtService.parseToken(form.getCode(), - JwtService.FORGOT_PASSWORD_AUDIENCE); + JWTClaimsSet claims = externalTokenService.parseToken(form.getCode(), + ExternalTokenService.FORGOT_PASSWORD_AUDIENCE); String email = claims.getSubject(); @@ -574,7 +581,8 @@ public void requestEmailChange(U user, @Valid U updatedUser) { */ protected void mailChangeEmailLink(U user) { - String changeEmailCode = jwtService.createToken(JwtService.CHANGE_EMAIL_AUDIENCE, + String changeEmailCode = externalTokenService.createToken( + ExternalTokenService.CHANGE_EMAIL_AUDIENCE, user.getId().toString(), properties.getJwt().getExpirationMillis(), LecUtils.mapOf("newEmail", user.getNewEmail())); @@ -635,8 +643,8 @@ public void changeEmail(ID userId, @Valid @NotBlank String changeEmailCode) { LexUtils.validate(StringUtils.isNotBlank(user.getNewEmail()), "com.naturalprogrammer.spring.blank.newEmail").go(); - JWTClaimsSet claims = jwtService.parseToken(changeEmailCode, - JwtService.CHANGE_EMAIL_AUDIENCE, + JWTClaimsSet claims = externalTokenService.parseToken(changeEmailCode, + ExternalTokenService.CHANGE_EMAIL_AUDIENCE, user.getCredentialsUpdatedMillis()); LecUtils.ensureAuthority( @@ -719,7 +727,7 @@ public String fetchNewToken(Optional expirationMillis, currentUser.isGoodAdmin(), "com.naturalprogrammer.spring.notGoodAdminOrSameUser"); return LecUtils.TOKEN_PREFIX + - jwtService.createToken(JwtService.AUTH_AUDIENCE, username, + authTokenService.createToken(AuthTokenService.AUTH_AUDIENCE, username, expirationMillis.orElse(properties.getJwt().getExpirationMillis())); } @@ -751,16 +759,16 @@ protected void hideConfidentialFields(U user) { @PreAuthorize("isAuthenticated()") public Map fetchFullToken(String authHeader) { - LecUtils.ensureCredentials(jwtService.parseClaim(authHeader.substring(LecUtils.TOKEN_PREFIX_LENGTH), - JwtService.USER_CLAIM) == null, "com.naturalprogrammer.spring.fullTokenNotAllowed"); + LecUtils.ensureCredentials(authTokenService.parseClaim(authHeader.substring(LecUtils.TOKEN_PREFIX_LENGTH), + AuthTokenService.USER_CLAIM) == null, "com.naturalprogrammer.spring.fullTokenNotAllowed"); UserDto currentUser = LecwUtils.currentUser(); - Map claimMap = Collections.singletonMap(JwtService.USER_CLAIM, + Map claimMap = Collections.singletonMap(AuthTokenService.USER_CLAIM, LecUtils.serialize(currentUser)); // Not serializing converts it to a JsonNode Map tokenMap = Collections.singletonMap("token", LecUtils.TOKEN_PREFIX + - jwtService.createToken(JwtService.AUTH_AUDIENCE, currentUser.getUsername(), + authTokenService.createToken(AuthTokenService.AUTH_AUDIENCE, currentUser.getUsername(), Long.valueOf(properties.getJwt().getShortLivedMillis()), claimMap)); @@ -773,9 +781,8 @@ public Map fetchFullToken(String authHeader) { */ public void addAuthHeader(HttpServletResponse response, String username, Long expirationMillis) { - response.addHeader(LecUtils.TOKEN_RESPONSE_HEADER_NAME, - LecUtils.TOKEN_PREFIX + - jwtService.createToken(JwtService.AUTH_AUDIENCE, username, expirationMillis)); + response.addHeader(LecUtils.TOKEN_RESPONSE_HEADER_NAME, LecUtils.TOKEN_PREFIX + + authTokenService.createToken(AuthTokenService.AUTH_AUDIENCE, username, expirationMillis)); } diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonJpaSecurityConfig.java b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonJpaSecurityConfig.java index 4df47b69..16354a9c 100644 --- a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonJpaSecurityConfig.java +++ b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonJpaSecurityConfig.java @@ -5,7 +5,6 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.crypto.password.PasswordEncoder; -import org.springframework.security.web.authentication.AuthenticationFailureHandler; import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; @@ -119,7 +118,7 @@ protected void oauth2Client(HttpSecurity http) throws Exception { */ protected void tokenAuthentication(HttpSecurity http) throws Exception { - http.addFilterBefore(new LemonJpaTokenAuthenticationFilter(jwtService, userDetailsService), + http.addFilterBefore(new LemonJpaTokenAuthenticationFilter(authTokenService, userDetailsService), UsernamePasswordAuthenticationFilter.class); } } diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonJpaTokenAuthenticationFilter.java b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonJpaTokenAuthenticationFilter.java index 4c09b4e5..866378e7 100644 --- a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonJpaTokenAuthenticationFilter.java +++ b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonJpaTokenAuthenticationFilter.java @@ -6,7 +6,7 @@ import org.apache.commons.logging.LogFactory; import org.springframework.security.core.userdetails.UsernameNotFoundException; -import com.naturalprogrammer.spring.lemon.commons.security.JwtService; +import com.naturalprogrammer.spring.lemon.commons.security.AuthTokenService; import com.naturalprogrammer.spring.lemon.commons.security.UserDto; import com.naturalprogrammer.spring.lemon.commonsweb.security.LemonCommonsWebTokenAuthenticationFilter; import com.naturalprogrammer.spring.lemon.domain.AbstractUser; @@ -20,10 +20,10 @@ public class LemonJpaTokenAuthenticationFilter, ID ex private LemonUserDetailsService userDetailsService; - public LemonJpaTokenAuthenticationFilter(JwtService jwtService, + public LemonJpaTokenAuthenticationFilter(AuthTokenService authTokenService, LemonUserDetailsService userDetailsService) { - super(jwtService); + super(authTokenService); this.userDetailsService = userDetailsService; log.info("Created"); diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/OAuth2AuthenticationSuccessHandler.java b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/OAuth2AuthenticationSuccessHandler.java index 448f1270..f88a0b08 100644 --- a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/OAuth2AuthenticationSuccessHandler.java +++ b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/OAuth2AuthenticationSuccessHandler.java @@ -11,31 +11,26 @@ import org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler; import com.naturalprogrammer.spring.lemon.commons.LemonProperties; -import com.naturalprogrammer.spring.lemon.commons.security.JwtService; +import com.naturalprogrammer.spring.lemon.commons.security.AuthTokenService; import com.naturalprogrammer.spring.lemon.commons.security.UserDto; import com.naturalprogrammer.spring.lemon.commonsweb.util.LecwUtils; +import lombok.AllArgsConstructor; + /** * Authentication success handler for redirecting the * OAuth2 signed in user to a URL with a short lived auth token * * @author Sanjay Patel */ +@AllArgsConstructor public class OAuth2AuthenticationSuccessHandler extends SimpleUrlAuthenticationSuccessHandler { private static final Log log = LogFactory.getLog(OAuth2AuthenticationSuccessHandler.class); private LemonProperties properties; - private JwtService jwtService; - - public OAuth2AuthenticationSuccessHandler(LemonProperties properties, JwtService jwtService) { - - this.properties = properties; - this.jwtService = jwtService; - - log.info("Created"); - } + private AuthTokenService authTokenService; @Override protected String determineTargetUrl(HttpServletRequest request, @@ -43,8 +38,8 @@ protected String determineTargetUrl(HttpServletRequest request, UserDto currentUser = LecwUtils.currentUser(); - String shortLivedAuthToken = jwtService.createToken( - JwtService.AUTH_AUDIENCE, + String shortLivedAuthToken = authTokenService.createToken( + AuthTokenService.AUTH_AUDIENCE, currentUser.getUsername(), (long) properties.getJwt().getShortLivedMillis()); diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/util/LemonUtils.java b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/util/LemonUtils.java index 017d13fc..7065e9ff 100644 --- a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/util/LemonUtils.java +++ b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/util/LemonUtils.java @@ -8,8 +8,8 @@ import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContextHolder; -import com.naturalprogrammer.spring.lemon.commons.security.JwtService; import com.naturalprogrammer.spring.lemon.commons.security.LemonPrincipal; +import com.naturalprogrammer.spring.lemon.commons.security.LemonTokenService; import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; import com.naturalprogrammer.spring.lemon.commonsjpa.LemonEntity; import com.naturalprogrammer.spring.lemon.domain.AbstractUser; @@ -71,7 +71,7 @@ void ensureCorrectVersion(LemonEntity original, LemonEntity updated) { public static , ID extends Serializable> void ensureCredentialsUpToDate(JWTClaimsSet claims, U user) { - long issueTime = (long) claims.getClaim(JwtService.LEMON_IAT); + long issueTime = (long) claims.getClaim(LemonTokenService.LEMON_IAT); LecUtils.ensureCredentials(issueTime >= user.getCredentialsUpdatedMillis(), "com.naturalprogrammer.spring.obsoleteToken"); diff --git a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveAutoConfiguration.java b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveAutoConfiguration.java index c8997545..bfaee84f 100644 --- a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveAutoConfiguration.java +++ b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveAutoConfiguration.java @@ -12,7 +12,7 @@ import org.springframework.security.core.userdetails.UserDetailsService; import com.naturalprogrammer.spring.lemon.commons.domain.IdConverter; -import com.naturalprogrammer.spring.lemon.commons.security.JwtService; +import com.naturalprogrammer.spring.lemon.commons.security.AuthTokenService; import com.naturalprogrammer.spring.lemon.commonsmongo.LemonCommonsMongoAutoConfiguration; import com.naturalprogrammer.spring.lemon.exceptions.util.LexUtils; import com.naturalprogrammer.spring.lemonreactive.domain.AbstractMongoUser; @@ -44,12 +44,12 @@ IdConverter idConverter(LemonReactiveService lemonService) { @ConditionalOnMissingBean(LemonReactiveSecurityConfig.class) public , ID extends Serializable> LemonReactiveSecurityConfig lemonReactiveSecurityConfig( - JwtService jwtService, + AuthTokenService authTokenService, LemonReactiveUserDetailsService userDetailsService) { log.info("Configuring LemonReactiveSecurityConfig ..."); - return new LemonReactiveSecurityConfig(jwtService, userDetailsService); + return new LemonReactiveSecurityConfig(authTokenService, userDetailsService); } diff --git a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveController.java b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveController.java index d645f294..b8ced1a4 100644 --- a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveController.java +++ b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveController.java @@ -29,7 +29,6 @@ import com.naturalprogrammer.spring.lemon.commons.LemonProperties; import com.naturalprogrammer.spring.lemon.commons.domain.ChangePasswordForm; import com.naturalprogrammer.spring.lemon.commons.domain.ResetPasswordForm; -import com.naturalprogrammer.spring.lemon.commons.security.JwtService; import com.naturalprogrammer.spring.lemon.commons.security.LemonPrincipal; import com.naturalprogrammer.spring.lemon.commons.security.UserDto; import com.naturalprogrammer.spring.lemonreactive.domain.AbstractMongoUser; @@ -51,18 +50,15 @@ public class LemonReactiveController private static final Log log = LogFactory.getLog(LemonReactiveController.class); protected long jwtExpirationMillis; - protected JwtService jwtService; protected LemonReactiveService lemonReactiveService; @Autowired public void createLemonController( LemonProperties properties, - LemonReactiveService lemonReactiveService, - JwtService jwtService) { + LemonReactiveService lemonReactiveService) { this.jwtExpirationMillis = properties.getJwt().getExpirationMillis(); this.lemonReactiveService = lemonReactiveService; - this.jwtService = jwtService; log.info("Created"); } diff --git a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveService.java b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveService.java index d4fdfdd0..cf4e1ca9 100644 --- a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveService.java +++ b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveService.java @@ -27,7 +27,8 @@ import com.naturalprogrammer.spring.lemon.commons.domain.ResetPasswordForm; import com.naturalprogrammer.spring.lemon.commons.mail.LemonMailData; import com.naturalprogrammer.spring.lemon.commons.mail.MailSender; -import com.naturalprogrammer.spring.lemon.commons.security.JwtService; +import com.naturalprogrammer.spring.lemon.commons.security.AuthTokenService; +import com.naturalprogrammer.spring.lemon.commons.security.ExternalTokenService; import com.naturalprogrammer.spring.lemon.commons.security.UserDto; import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; import com.naturalprogrammer.spring.lemon.commons.util.UserUtils; @@ -55,7 +56,8 @@ public abstract class LemonReactiveService protected MailSender mailSender; protected AbstractMongoUserRepository userRepository; protected ReactiveUserDetailsService userDetailsService; - protected JwtService jwtService; + protected AuthTokenService authTokenService; + protected ExternalTokenService externalTokenService; @Autowired public void createLemonService(LemonProperties properties, @@ -63,14 +65,15 @@ public void createLemonService(LemonProperties properties, MailSender mailSender, AbstractMongoUserRepository userRepository, ReactiveUserDetailsService userDetailsService, - JwtService jwtService) { + ExternalTokenService externalTokenService) { this.properties = properties; this.passwordEncoder = passwordEncoder; this.mailSender = mailSender; this.userRepository = userRepository; this.userDetailsService = userDetailsService; - this.jwtService = jwtService; + this.authTokenService = authTokenService; + this.externalTokenService = externalTokenService; log.info("Created"); } @@ -232,7 +235,7 @@ protected void sendVerificationMail(final U user) { log.debug("Sending verification mail to: " + user); - String verificationCode = jwtService.createToken(JwtService.VERIFY_AUDIENCE, + String verificationCode = externalTokenService.createToken(ExternalTokenService.VERIFY_AUDIENCE, user.getId().toString(), properties.getJwt().getExpirationMillis(), LecUtils.mapOf("email", user.getEmail())); @@ -326,7 +329,8 @@ public U verifyUser(Tuple2> tuple) { LexUtils.validate(user.hasRole(UserUtils.Role.UNVERIFIED), "com.naturalprogrammer.spring.alreadyVerified").go(); - JWTClaimsSet claims = jwtService.parseToken(verificationCode, JwtService.VERIFY_AUDIENCE, user.getCredentialsUpdatedMillis()); + JWTClaimsSet claims = externalTokenService.parseToken( + verificationCode, ExternalTokenService.VERIFY_AUDIENCE, user.getCredentialsUpdatedMillis()); LecUtils.ensureAuthority( claims.getSubject().equals(user.getId().toString()) && @@ -362,7 +366,8 @@ public void mailForgotPasswordLink(U user) { log.debug("Mailing forgot password link to user: " + user); - String forgotPasswordCode = jwtService.createToken(JwtService.FORGOT_PASSWORD_AUDIENCE, + String forgotPasswordCode = externalTokenService.createToken( + ExternalTokenService.FORGOT_PASSWORD_AUDIENCE, user.getEmail(), properties.getJwt().getExpirationMillis()); // make the link @@ -396,8 +401,8 @@ public Mono resetPassword(Mono resetPasswordForm) { log.debug("Resetting password ..."); - JWTClaimsSet claims = jwtService.parseToken(form.getCode(), - JwtService.FORGOT_PASSWORD_AUDIENCE); + JWTClaimsSet claims = externalTokenService.parseToken(form.getCode(), + ExternalTokenService.FORGOT_PASSWORD_AUDIENCE); String email = claims.getSubject(); @@ -451,7 +456,7 @@ protected void addAuthHeader(ServerHttpResponse response, UserDto userDto, long log.debug("Adding auth header for " + userDto.getUsername()); response.getHeaders().add(LecUtils.TOKEN_RESPONSE_HEADER_NAME, LecUtils.TOKEN_PREFIX + - jwtService.createToken(JwtService.AUTH_AUDIENCE, userDto.getUsername(), expirationMillis)); + authTokenService.createToken(AuthTokenService.AUTH_AUDIENCE, userDto.getUsername(), expirationMillis)); } @@ -659,7 +664,8 @@ protected void requestEmailChange(Tuple3 tuple) { */ protected void mailChangeEmailLink(U user) { - String changeEmailCode = jwtService.createToken(JwtService.CHANGE_EMAIL_AUDIENCE, + String changeEmailCode = externalTokenService.createToken( + ExternalTokenService.CHANGE_EMAIL_AUDIENCE, user.getId().toString(), properties.getJwt().getExpirationMillis(), LecUtils.mapOf("newEmail", user.getNewEmail())); @@ -734,8 +740,8 @@ protected U validateChangeEmail(Tuple2> tuple) LexUtils.validate(StringUtils.isNotBlank(user.getNewEmail()), "com.naturalprogrammer.spring.blank.newEmail").go(); - JWTClaimsSet claims = jwtService.parseToken(code, - JwtService.CHANGE_EMAIL_AUDIENCE, + JWTClaimsSet claims = externalTokenService.parseToken(code, + ExternalTokenService.CHANGE_EMAIL_AUDIENCE, user.getCredentialsUpdatedMillis()); LecUtils.ensureAuthority( @@ -787,7 +793,7 @@ public Mono> fetchNewToken(ServerWebExchange exchange) { currentUser.isGoodAdmin(), "com.naturalprogrammer.spring.notGoodAdminOrSameUser"); return Collections.singletonMap("token", LecUtils.TOKEN_PREFIX + - jwtService.createToken(JwtService.AUTH_AUDIENCE, username, expirationMillis)); + authTokenService.createToken(authTokenService.AUTH_AUDIENCE, username, expirationMillis)); }); } @@ -795,18 +801,18 @@ public Mono> fetchNewToken(ServerWebExchange exchange) { @PreAuthorize("isAuthenticated()") public Mono> fetchFullToken(String authHeader) { - LecUtils.ensureCredentials(jwtService.parseClaim(authHeader.substring(LecUtils.TOKEN_PREFIX_LENGTH), - JwtService.USER_CLAIM) == null, "com.naturalprogrammer.spring.fullTokenNotAllowed"); + LecUtils.ensureCredentials(authTokenService.parseClaim(authHeader.substring(LecUtils.TOKEN_PREFIX_LENGTH), + AuthTokenService.USER_CLAIM) == null, "com.naturalprogrammer.spring.fullTokenNotAllowed"); return LecrUtils.currentUser().map(optionalUser -> { UserDto currentUser = optionalUser.get(); - Map claimMap = Collections.singletonMap(JwtService.USER_CLAIM, + Map claimMap = Collections.singletonMap(AuthTokenService.USER_CLAIM, LecUtils.serialize(currentUser)); // Not serializing converts it to a JsonNode Map tokenMap = Collections.singletonMap("token", LecUtils.TOKEN_PREFIX + - jwtService.createToken(JwtService.AUTH_AUDIENCE, currentUser.getUsername(), + authTokenService.createToken(AuthTokenService.AUTH_AUDIENCE, currentUser.getUsername(), Long.valueOf(properties.getJwt().getShortLivedMillis()), claimMap)); diff --git a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/security/LemonReactiveSecurityConfig.java b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/security/LemonReactiveSecurityConfig.java index e6d96e71..1a1a68de 100644 --- a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/security/LemonReactiveSecurityConfig.java +++ b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/security/LemonReactiveSecurityConfig.java @@ -8,7 +8,7 @@ import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.security.web.server.authentication.WebFilterChainServerAuthenticationSuccessHandler; -import com.naturalprogrammer.spring.lemon.commons.security.JwtService; +import com.naturalprogrammer.spring.lemon.commons.security.AuthTokenService; import com.naturalprogrammer.spring.lemon.commons.security.UserDto; import com.naturalprogrammer.spring.lemon.commonsreactive.security.LemonCommonsReactiveSecurityConfig; import com.naturalprogrammer.spring.lemonreactive.domain.AbstractMongoUser; @@ -23,10 +23,10 @@ public class LemonReactiveSecurityConfig , ID ex protected LemonReactiveUserDetailsService userDetailsService; - public LemonReactiveSecurityConfig(JwtService jwtService, + public LemonReactiveSecurityConfig(AuthTokenService authTokenService, LemonReactiveUserDetailsService userDetailsService) { - super(jwtService); + super(authTokenService); this.userDetailsService = userDetailsService; log.info("Created"); } diff --git a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/util/LerUtils.java b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/util/LerUtils.java index f9daba48..02b705e0 100644 --- a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/util/LerUtils.java +++ b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/util/LerUtils.java @@ -5,7 +5,7 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import com.naturalprogrammer.spring.lemon.commons.security.JwtService; +import com.naturalprogrammer.spring.lemon.commons.security.LemonTokenService; import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; import com.naturalprogrammer.spring.lemonreactive.domain.AbstractMongoUser; import com.nimbusds.jwt.JWTClaimsSet; @@ -26,7 +26,7 @@ public class LerUtils { public static , ID extends Serializable> void ensureCredentialsUpToDate(JWTClaimsSet claims, U user) { - long issueTime = (long) claims.getClaim(JwtService.LEMON_IAT); + long issueTime = (long) claims.getClaim(LemonTokenService.LEMON_IAT); log.debug("Ensuring credentials up to date. Issue time = " + issueTime + ". User's credentials updated at" + user.getCredentialsUpdatedMillis()); From 203dcb3e3c53a64b7bd331a48f2c6d568dfc8555 Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Thu, 15 Nov 2018 22:46:50 +0530 Subject: [PATCH 075/116] Added JWS Service --- .../LemonCommonsAutoConfiguration.java | 8 +- .../commons/security/AbstractJwtService.java | 90 +++++++++++++ .../commons/security/LemonJweService.java | 87 +------------ .../commons/security/LemonJwsService.java | 80 ++++++++++++ .../commons/security/LemonTokenService.java | 20 --- .../security/LemonJweServiceTests.java | 123 ------------------ .../security/LemonJwtServiceTests.java | 109 ++++++++++++++++ .../lemonreactive/LemonReactiveService.java | 1 + 8 files changed, 291 insertions(+), 227 deletions(-) create mode 100644 spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/AbstractJwtService.java create mode 100644 spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/LemonJwsService.java delete mode 100644 spring-lemon-commons/src/test/java/com/naturalprogrammer/lemon/commons/security/LemonJweServiceTests.java create mode 100644 spring-lemon-commons/src/test/java/com/naturalprogrammer/spring/lemon/commons/security/LemonJwtServiceTests.java diff --git a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/LemonCommonsAutoConfiguration.java b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/LemonCommonsAutoConfiguration.java index 2d8269c3..e0854272 100644 --- a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/LemonCommonsAutoConfiguration.java +++ b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/LemonCommonsAutoConfiguration.java @@ -24,10 +24,12 @@ import com.naturalprogrammer.spring.lemon.commons.security.AuthTokenService; import com.naturalprogrammer.spring.lemon.commons.security.ExternalTokenService; import com.naturalprogrammer.spring.lemon.commons.security.LemonJweService; +import com.naturalprogrammer.spring.lemon.commons.security.LemonJwsService; import com.naturalprogrammer.spring.lemon.commons.security.LemonPermissionEvaluator; import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; import com.naturalprogrammer.spring.lemon.commons.validation.CaptchaValidator; import com.naturalprogrammer.spring.lemon.exceptions.LemonExceptionsAutoConfiguration; +import com.nimbusds.jose.JOSEException; import com.nimbusds.jose.KeyLengthException; @Configuration @@ -60,15 +62,15 @@ public LemonProperties lemonProperties() { */ @Bean @ConditionalOnMissingBean(AuthTokenService.class) - public AuthTokenService authTokenService(LemonProperties properties) throws KeyLengthException { + public AuthTokenService authTokenService(LemonProperties properties) throws JOSEException { log.info("Configuring AuthTokenService"); - return new LemonJweService(properties.getJwt().getSecret()); + return new LemonJwsService(properties.getJwt().getSecret()); } /** - * Configures AuthTokenService if missing + * Configures ExternalTokenService if missing */ @Bean @ConditionalOnMissingBean(ExternalTokenService.class) diff --git a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/AbstractJwtService.java b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/AbstractJwtService.java new file mode 100644 index 00000000..d3430b3d --- /dev/null +++ b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/AbstractJwtService.java @@ -0,0 +1,90 @@ +package com.naturalprogrammer.spring.lemon.commons.security; + +import java.util.Date; +import java.util.HashMap; +import java.util.Map; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; +import com.nimbusds.jose.Payload; +import com.nimbusds.jwt.JWTClaimsSet; + +/** + * Common JWT Service + */ +public abstract class AbstractJwtService implements LemonTokenService { + + private static final Log log = LogFactory.getLog(AbstractJwtService.class); + + protected Payload createPayload(String aud, String subject, Long expirationMillis, Map claimMap) { + + JWTClaimsSet.Builder builder = new JWTClaimsSet.Builder(); + + builder + //.issueTime(new Date()) + .expirationTime(new Date(System.currentTimeMillis() + expirationMillis)) + .audience(aud) + .subject(subject) + .claim(LEMON_IAT, System.currentTimeMillis()); + + claimMap.forEach(builder::claim); + + JWTClaimsSet claims = builder.build(); + + return new Payload(claims.toJSONObject()); + } + + + @Override + public String createToken(String audience, String subject, Long expirationMillis) { + + return createToken(audience, subject, expirationMillis, new HashMap<>()); + } + + + @Override + public JWTClaimsSet parseToken(String token, String audience) { + + JWTClaimsSet claims = parseToken(token); + LecUtils.ensureCredentials(audience != null && + claims.getAudience().contains(audience), + "com.naturalprogrammer.spring.wrong.audience"); + + long expirationTime = claims.getExpirationTime().getTime(); + long currentTime = System.currentTimeMillis(); + + log.debug("Parsing JWT. Expiration time = " + expirationTime + + ". Current time = " + currentTime); + + LecUtils.ensureCredentials(expirationTime >= currentTime, + "com.naturalprogrammer.spring.expiredToken"); + + return claims; + } + + + @Override + public JWTClaimsSet parseToken(String token, String audience, long issuedAfter) { + + JWTClaimsSet claims = parseToken(token, audience); + + long issueTime = (long) claims.getClaim(LEMON_IAT); + LecUtils.ensureCredentials(issueTime >= issuedAfter, + "com.naturalprogrammer.spring.obsoleteToken"); + + return claims; + } + + + @Override + public T parseClaim(String token, String claim) { + + JWTClaimsSet claims = parseToken(token); + return (T) claims.getClaim(claim); + } + + + protected abstract JWTClaimsSet parseToken(String token); +} diff --git a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/LemonJweService.java b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/LemonJweService.java index 2dfc6584..28f82a8f 100644 --- a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/LemonJweService.java +++ b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/LemonJweService.java @@ -1,15 +1,12 @@ package com.naturalprogrammer.spring.lemon.commons.security; import java.text.ParseException; -import java.util.Date; -import java.util.HashMap; import java.util.Map; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.security.authentication.BadCredentialsException; -import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; import com.nimbusds.jose.EncryptionMethod; import com.nimbusds.jose.JOSEException; import com.nimbusds.jose.JWEAlgorithm; @@ -29,14 +26,14 @@ import com.nimbusds.jwt.proc.DefaultJWTProcessor; /** - * JWT Service + * JWE Service * * References: * * https://connect2id.com/products/nimbus-jose-jwt/examples/jwe-with-shared-key * https://connect2id.com/products/nimbus-jose-jwt/examples/validating-jwt-access-tokens */ -public class LemonJweService implements AuthTokenService, ExternalTokenService { +public class LemonJweService extends AbstractJwtService implements ExternalTokenService { private static final Log log = LogFactory.getLog(LemonJweService.class); @@ -60,29 +57,13 @@ public LemonJweService(String secret) throws KeyLengthException { jwtProcessor.setJWEKeySelector(jweKeySelector); } - /* (non-Javadoc) - * @see com.naturalprogrammer.spring.lemon.commons.security.JwtService#createToken(java.lang.String, java.lang.String, java.lang.Long, java.util.Map) - */ + @Override public String createToken(String aud, String subject, Long expirationMillis, Map claimMap) { - JWTClaimsSet.Builder builder = new JWTClaimsSet.Builder(); - - builder - //.issueTime(new Date()) - .expirationTime(new Date(System.currentTimeMillis() + expirationMillis)) - .audience(aud) - .subject(subject) - .claim(LEMON_IAT, System.currentTimeMillis()); - - //claimMap.put("iat", new Date()); - claimMap.forEach(builder::claim); - - JWTClaimsSet claims = builder.build(); - - Payload payload = new Payload(claims.toJSONObject()); - - // Create the JWE object and encrypt it + Payload payload = createPayload(aud, subject, expirationMillis, claimMap); + + // Create the JWE object and encrypt it JWEObject jweObject = new JWEObject(header, payload); try { @@ -97,64 +78,8 @@ public String createToken(String aud, String subject, Long expirationMillis, Map // Serialize to compact JOSE form... return jweObject.serialize(); } - - /* (non-Javadoc) - * @see com.naturalprogrammer.spring.lemon.commons.security.JwtService#createToken(java.lang.String, java.lang.String, java.lang.Long) - */ - @Override - public String createToken(String audience, String subject, Long expirationMillis) { - - return createToken(audience, subject, expirationMillis, new HashMap<>()); - } - - /* (non-Javadoc) - * @see com.naturalprogrammer.spring.lemon.commons.security.JwtService#parseToken(java.lang.String, java.lang.String) - */ - @Override - public JWTClaimsSet parseToken(String token, String audience) { - - JWTClaimsSet claims = parseToken(token); - LecUtils.ensureCredentials(audience != null && - claims.getAudience().contains(audience), - "com.naturalprogrammer.spring.wrong.audience"); - - long expirationTime = claims.getExpirationTime().getTime(); - long currentTime = System.currentTimeMillis(); - - log.debug("Parsing JWT. Expiration time = " + expirationTime - + ". Current time = " + currentTime); - - LecUtils.ensureCredentials(expirationTime >= currentTime, - "com.naturalprogrammer.spring.expiredToken"); - - return claims; - } - /* (non-Javadoc) - * @see com.naturalprogrammer.spring.lemon.commons.security.JwtService#parseToken(java.lang.String, java.lang.String, long) - */ - @Override - public JWTClaimsSet parseToken(String token, String audience, long issuedAfter) { - - JWTClaimsSet claims = parseToken(token, audience); - - long issueTime = (long) claims.getClaim(LEMON_IAT); - LecUtils.ensureCredentials(issueTime >= issuedAfter, - "com.naturalprogrammer.spring.obsoleteToken"); - - return claims; - } - /* (non-Javadoc) - * @see com.naturalprogrammer.spring.lemon.commons.security.JwtService#parseClaim(java.lang.String, java.lang.String) - */ - @Override - public T parseClaim(String token, String claim) { - - JWTClaimsSet claims = parseToken(token); - return (T) claims.getClaim(claim); - } - /** * Parses a token */ diff --git a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/LemonJwsService.java b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/LemonJwsService.java new file mode 100644 index 00000000..5de00802 --- /dev/null +++ b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/LemonJwsService.java @@ -0,0 +1,80 @@ +package com.naturalprogrammer.spring.lemon.commons.security; + +import java.text.ParseException; +import java.util.Map; + +import org.springframework.security.authentication.BadCredentialsException; + +import com.nimbusds.jose.JOSEException; +import com.nimbusds.jose.JWSAlgorithm; +import com.nimbusds.jose.JWSHeader; +import com.nimbusds.jose.JWSObject; +import com.nimbusds.jose.JWSSigner; +import com.nimbusds.jose.JWSVerifier; +import com.nimbusds.jose.Payload; +import com.nimbusds.jose.crypto.MACSigner; +import com.nimbusds.jose.crypto.MACVerifier; +import com.nimbusds.jwt.JWTClaimsSet; + +/** + * JWS Service + * + * Reference: https://connect2id.com/products/nimbus-jose-jwt/examples/jws-with-hmac + */ +public class LemonJwsService extends AbstractJwtService implements AuthTokenService { + + private JWSSigner signer; + private JWSVerifier verifier; + + + + public LemonJwsService(String secret) throws JOSEException { + + byte[] secretKey = secret.getBytes(); + signer = new MACSigner(secret); + verifier = new MACVerifier(secret); + } + + @Override + public String createToken(String aud, String subject, Long expirationMillis, Map claimMap) { + + Payload payload = createPayload(aud, subject, expirationMillis, claimMap); + + // Prepare JWS object + JWSObject jwsObject = new JWSObject(new JWSHeader(JWSAlgorithm.HS256), payload); + + try { + // Apply the HMAC + jwsObject.sign(signer); + + } catch (JOSEException e) { + + throw new RuntimeException(e); + } + + // To serialize to compact form, produces something like + // eyJhbGciOiJIUzI1NiJ9.SGVsbG8sIHdvcmxkIQ.onO9Ihudz3WkiauDO2Uhyuz0Y18UASXlSc1eS0NkWyA + return jwsObject.serialize(); + } + + /** + * Parses a token + */ + protected JWTClaimsSet parseToken(String token) { + + // Parse the JWS and verify it, e.g. on client-side + JWSObject jwsObject; + + try { + jwsObject = JWSObject.parse(token); + if (jwsObject.verify(verifier)) + return JWTClaimsSet.parse(jwsObject.getPayload().toJSONObject()); + + } catch (JOSEException | ParseException e) { + + throw new BadCredentialsException(e.getMessage()); + } + + throw new BadCredentialsException("JWS verification failed!"); + } +} diff --git a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/LemonTokenService.java b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/LemonTokenService.java index 964d1481..99c7c6b1 100644 --- a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/LemonTokenService.java +++ b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/LemonTokenService.java @@ -8,29 +8,9 @@ public interface LemonTokenService { String LEMON_IAT = "lemon-iat"; - /** - * Creates a token - */ String createToken(String aud, String subject, Long expirationMillis, Map claimMap); - - /** - * Creates a token - */ String createToken(String audience, String subject, Long expirationMillis); - - /** - * Parses a token - */ JWTClaimsSet parseToken(String token, String audience); - - /** - * Parses a token - */ JWTClaimsSet parseToken(String token, String audience, long issuedAfter); - - /** - * Parses a claim - */ T parseClaim(String token, String claim); - } \ No newline at end of file diff --git a/spring-lemon-commons/src/test/java/com/naturalprogrammer/lemon/commons/security/LemonJweServiceTests.java b/spring-lemon-commons/src/test/java/com/naturalprogrammer/lemon/commons/security/LemonJweServiceTests.java deleted file mode 100644 index 1cb9f8c9..00000000 --- a/spring-lemon-commons/src/test/java/com/naturalprogrammer/lemon/commons/security/LemonJweServiceTests.java +++ /dev/null @@ -1,123 +0,0 @@ -package com.naturalprogrammer.lemon.commons.security; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - -import java.security.SecureRandom; -import java.text.ParseException; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.junit.Assert; -import org.junit.Test; -import org.springframework.security.authentication.BadCredentialsException; - -import com.naturalprogrammer.spring.lemon.commons.security.LemonJweService; -import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; -import com.nimbusds.jose.JOSEException; -import com.nimbusds.jose.JWSAlgorithm; -import com.nimbusds.jose.JWSHeader; -import com.nimbusds.jose.JWSObject; -import com.nimbusds.jose.JWSSigner; -import com.nimbusds.jose.JWSVerifier; -import com.nimbusds.jose.KeyLengthException; -import com.nimbusds.jose.Payload; -import com.nimbusds.jose.crypto.MACSigner; -import com.nimbusds.jose.crypto.MACVerifier; -import com.nimbusds.jwt.JWTClaimsSet; - -public class LemonJweServiceTests { - - private static final Log log = LogFactory.getLog(LemonJweServiceTests.class); - - // An aes-128-cbc key generated at https://asecuritysite.com/encryption/keygen (take the "key" field) - private static final String SECRET1 = "926D96C90030DD58429D2751AC1BDBBC"; - private static final String SECRET2 = "538518AB685B514685DA8055C03DDA63"; - - private LemonJweService service1; - private LemonJweService service2; - - public LemonJweServiceTests() throws KeyLengthException { - - service1 = new LemonJweService(SECRET1); - service2 = new LemonJweService(SECRET2); - } - - @Test - public void testJwtParseToken() { - - log.info("Creating token ..."); - String token = service1.createToken("auth", "subject", 5000L, - LecUtils.mapOf("username", "abc@example.com")); - - log.info("Parsing token ..."); - JWTClaimsSet claims = service1.parseToken(token, "auth"); - - log.info("Parsed token."); - Assert.assertEquals("subject", claims.getSubject()); - Assert.assertEquals("abc@example.com", claims.getClaim("username")); - } - - @Test - public void testJws() throws KeyLengthException, JOSEException, ParseException { - - // We need a 256-bit key for HS256 which must be pre-shared - byte[] sharedKey = new byte[32]; - new SecureRandom().nextBytes(sharedKey); - - JWSSigner signer = new MACSigner(sharedKey); - JWSVerifier verifier = new MACVerifier(sharedKey); - - - log.info("Creating JWS token ..."); - // Create an HMAC-protected JWS object with some payload - JWSObject jwsObject = new JWSObject(new JWSHeader(JWSAlgorithm.HS256), - new Payload("Hello, world!")); - - // Apply the HMAC to the JWS object - jwsObject.sign(signer); - - String token = jwsObject.serialize(); - - // Output in URL-safe format - log.info("Created token: " + token); - - // To parse the JWS and verify it, e.g. on client-side - jwsObject = JWSObject.parse(token); - assertTrue(jwsObject.verify(verifier)); - assertEquals("Hello, world!", jwsObject.getPayload().toString()); - log.info("Parsed token."); - - - } - - @Test(expected = BadCredentialsException.class) - public void testJwtParseTokenWrongAudience() { - - String token = service1.createToken("auth", "subject", 5000L); - service1.parseToken(token, "auth2"); - } - - @Test(expected = BadCredentialsException.class) - public void testJwtParseTokenExpired() throws InterruptedException { - - String token = service1.createToken("auth", "subject", 1L); - Thread.sleep(1L); - service1.parseToken(token, "auth"); - } - - @Test(expected = BadCredentialsException.class) - public void testJwtParseTokenWrongSecret() { - - String token = service1.createToken("auth", "subject", 5000L); - service2.parseToken(token, "auth"); - } - - @Test(expected = BadCredentialsException.class) - public void testParseTokenCutoffTime() throws InterruptedException { - - String token = service1.createToken("auth", "subject", 5000L); - Thread.sleep(1L); - service1.parseToken(token, "auth", System.currentTimeMillis()); - } -} diff --git a/spring-lemon-commons/src/test/java/com/naturalprogrammer/spring/lemon/commons/security/LemonJwtServiceTests.java b/spring-lemon-commons/src/test/java/com/naturalprogrammer/spring/lemon/commons/security/LemonJwtServiceTests.java new file mode 100644 index 00000000..73adebfe --- /dev/null +++ b/spring-lemon-commons/src/test/java/com/naturalprogrammer/spring/lemon/commons/security/LemonJwtServiceTests.java @@ -0,0 +1,109 @@ +package com.naturalprogrammer.spring.lemon.commons.security; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.junit.Assert; +import org.junit.Test; +import org.springframework.security.authentication.BadCredentialsException; + +import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; +import com.nimbusds.jose.JOSEException; +import com.nimbusds.jwt.JWTClaimsSet; + +public class LemonJwtServiceTests { + + private static final Log log = LogFactory.getLog(LemonJwtServiceTests.class); + + // An aes-128-cbc key generated at https://asecuritysite.com/encryption/keygen (take the "key" field) + private static final String SECRET1 = "926D96C90030DD58429D2751AC1BDBBC"; + private static final String SECRET2 = "538518AB685B514685DA8055C03DDA63"; + + private LemonJweService jweService1; + private LemonJweService jweService2; + private LemonJwsService jwsService1; + private LemonJwsService jwsService2; + + public LemonJwtServiceTests() throws JOSEException { + + jweService1 = new LemonJweService(SECRET1); + jweService2 = new LemonJweService(SECRET2); + + jwsService1 = new LemonJwsService(SECRET1); + jwsService2 = new LemonJwsService(SECRET2); + } + + @Test + public void testParseToken() { + + testParseToken(jweService1); + testParseToken(jwsService1); + } + + private void testParseToken(LemonTokenService service) { + + log.info("Creating token ..." + service.getClass().getSimpleName()); + String token = service.createToken("auth", "subject", 5000L, + LecUtils.mapOf("username", "abc@example.com")); + + log.info("Parsing token ..."); + JWTClaimsSet claims = service.parseToken(token, "auth"); + + log.info("Parsed token."); + Assert.assertEquals("subject", claims.getSubject()); + Assert.assertEquals("abc@example.com", claims.getClaim("username")); + } + + @Test(expected = BadCredentialsException.class) + public void testParseTokenWrongAudience() { + + testParseTokenWrongAudience(jweService1); + testParseTokenWrongAudience(jwsService1); + } + + private void testParseTokenWrongAudience(LemonTokenService service) { + + String token = service.createToken("auth", "subject", 5000L); + service.parseToken(token, "auth2"); + } + + @Test(expected = BadCredentialsException.class) + public void testParseTokenExpired() throws InterruptedException { + + testParseTokenExpired(jweService1); + testParseTokenExpired(jwsService1); + } + + private void testParseTokenExpired(LemonTokenService service) throws InterruptedException { + + String token = service.createToken("auth", "subject", 1L); + Thread.sleep(1L); + service.parseToken(token, "auth"); + } + + @Test(expected = BadCredentialsException.class) + public void testParseTokenWrongSecret() { + + testParseTokenWrongSecret(jweService1, jweService2); + testParseTokenWrongSecret(jwsService1, jwsService2); + } + + private void testParseTokenWrongSecret(LemonTokenService service1, LemonTokenService service2) { + + String token = service1.createToken("auth", "subject", 5000L); + service2.parseToken(token, "auth"); + } + + @Test(expected = BadCredentialsException.class) + public void testParseTokenCutoffTime() throws InterruptedException { + + testParseTokenCutoffTime(jweService1); + testParseTokenCutoffTime(jwsService1); + } + + private void testParseTokenCutoffTime(LemonTokenService service) throws InterruptedException { + + String token = service.createToken("auth", "subject", 5000L); + Thread.sleep(1L); + service.parseToken(token, "auth", System.currentTimeMillis()); + } +} diff --git a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveService.java b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveService.java index cf4e1ca9..33c46e25 100644 --- a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveService.java +++ b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveService.java @@ -65,6 +65,7 @@ public void createLemonService(LemonProperties properties, MailSender mailSender, AbstractMongoUserRepository userRepository, ReactiveUserDetailsService userDetailsService, + AuthTokenService authTokenService, ExternalTokenService externalTokenService) { this.properties = properties; From aad66e37de912daa3a3d7340e82afe2b67d6e6f0 Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Thu, 15 Nov 2018 22:58:01 +0530 Subject: [PATCH 076/116] Fixed JWT unit tests --- .../security/LemonJwtServiceTests.java | 32 ++++++++++++++++--- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/spring-lemon-commons/src/test/java/com/naturalprogrammer/spring/lemon/commons/security/LemonJwtServiceTests.java b/spring-lemon-commons/src/test/java/com/naturalprogrammer/spring/lemon/commons/security/LemonJwtServiceTests.java index 73adebfe..dbb22cb2 100644 --- a/spring-lemon-commons/src/test/java/com/naturalprogrammer/spring/lemon/commons/security/LemonJwtServiceTests.java +++ b/spring-lemon-commons/src/test/java/com/naturalprogrammer/spring/lemon/commons/security/LemonJwtServiceTests.java @@ -54,12 +54,18 @@ private void testParseToken(LemonTokenService service) { } @Test(expected = BadCredentialsException.class) - public void testParseTokenWrongAudience() { + public void testParseJweTokenWrongAudience() { testParseTokenWrongAudience(jweService1); + } + + @Test(expected = BadCredentialsException.class) + public void testParseJwsTokenWrongAudience() { + testParseTokenWrongAudience(jwsService1); } + private void testParseTokenWrongAudience(LemonTokenService service) { String token = service.createToken("auth", "subject", 5000L); @@ -67,12 +73,17 @@ private void testParseTokenWrongAudience(LemonTokenService service) { } @Test(expected = BadCredentialsException.class) - public void testParseTokenExpired() throws InterruptedException { + public void testParseJweTokenExpired() throws InterruptedException { testParseTokenExpired(jweService1); - testParseTokenExpired(jwsService1); } + @Test(expected = BadCredentialsException.class) + public void testParseJwsTokenExpired() throws InterruptedException { + + testParseTokenExpired(jwsService1); + } + private void testParseTokenExpired(LemonTokenService service) throws InterruptedException { String token = service.createToken("auth", "subject", 1L); @@ -81,9 +92,14 @@ private void testParseTokenExpired(LemonTokenService service) throws Interrupted } @Test(expected = BadCredentialsException.class) - public void testParseTokenWrongSecret() { + public void testParseJweTokenWrongSecret() { testParseTokenWrongSecret(jweService1, jweService2); + } + + @Test(expected = BadCredentialsException.class) + public void testParseJwsTokenWrongSecret() { + testParseTokenWrongSecret(jwsService1, jwsService2); } @@ -94,12 +110,18 @@ private void testParseTokenWrongSecret(LemonTokenService service1, LemonTokenSer } @Test(expected = BadCredentialsException.class) - public void testParseTokenCutoffTime() throws InterruptedException { + public void testParseJweTokenCutoffTime() throws InterruptedException { testParseTokenCutoffTime(jweService1); + } + + @Test(expected = BadCredentialsException.class) + public void testParseJwsTokenCutoffTime() throws InterruptedException { + testParseTokenCutoffTime(jwsService1); } + private void testParseTokenCutoffTime(LemonTokenService service) throws InterruptedException { String token = service.createToken("auth", "subject", 5000L); From 63bc56b44b51e011bb33ed668f1b7283386d71b0 Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Fri, 16 Nov 2018 13:00:13 +0530 Subject: [PATCH 077/116] Renamed token services --- .../spring/lemondemo/ChangeEmailMvcTests.java | 18 +++---- .../lemondemo/ResetPasswordMvcTests.java | 8 +-- .../lemondemo/VerificationMvcTests.java | 12 ++--- .../spring/lemondemo/ChangeEmailTests.java | 18 +++---- .../spring/lemondemo/ResetPasswordTests.java | 8 +-- .../spring/lemondemo/VerificationTests.java | 12 ++--- ...LemonCommonsReactiveAutoConfiguration.java | 6 +-- .../LemonCommonsReactiveSecurityConfig.java | 6 +-- ...onCommonsWebTokenAuthenticationFilter.java | 6 +-- .../security/LemonWebSecurityConfig.java | 10 ++-- .../LemonCommonsAutoConfiguration.java | 12 ++--- ...okenService.java => BlueTokenService.java} | 2 +- ...kenService.java => GreenTokenService.java} | 2 +- .../commons/security/LemonJweService.java | 2 +- .../commons/security/LemonJwsService.java | 2 +- .../spring/lemon/commons/util/LecUtils.java | 4 +- .../spring/lemon/LemonAutoConfiguration.java | 6 +-- .../spring/lemon/LemonService.java | 52 +++++++++---------- .../security/LemonJpaSecurityConfig.java | 2 +- .../LemonJpaTokenAuthenticationFilter.java | 6 +-- .../OAuth2AuthenticationSuccessHandler.java | 8 +-- .../LemonReactiveAutoConfiguration.java | 6 +-- .../lemonreactive/LemonReactiveService.java | 50 +++++++++--------- .../security/LemonReactiveSecurityConfig.java | 6 +-- 24 files changed, 132 insertions(+), 132 deletions(-) rename spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/{AuthTokenService.java => BlueTokenService.java} (64%) rename spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/{ExternalTokenService.java => GreenTokenService.java} (73%) diff --git a/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/ChangeEmailMvcTests.java b/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/ChangeEmailMvcTests.java index 18aa018e..f4cba5e0 100644 --- a/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/ChangeEmailMvcTests.java +++ b/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/ChangeEmailMvcTests.java @@ -13,7 +13,7 @@ import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; -import com.naturalprogrammer.spring.lemon.commons.security.ExternalTokenService; +import com.naturalprogrammer.spring.lemon.commons.security.GreenTokenService; import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; import com.naturalprogrammer.spring.lemondemo.entities.User; @@ -24,7 +24,7 @@ public class ChangeEmailMvcTests extends AbstractMvcTests { private String changeEmailCode; @Autowired - private ExternalTokenService externalTokenService; + private GreenTokenService greenTokenService; @Before public void setUp() { @@ -33,8 +33,8 @@ public void setUp() { user.setNewEmail(NEW_EMAIL); userRepository.save(user); - changeEmailCode = externalTokenService.createToken( - ExternalTokenService.CHANGE_EMAIL_AUDIENCE, + changeEmailCode = greenTokenService.createToken( + GreenTokenService.CHANGE_EMAIL_AUDIENCE, Long.toString(UNVERIFIED_USER_ID), 60000L, LecUtils.mapOf("newEmail", NEW_EMAIL)); } @@ -76,7 +76,7 @@ public void testChangeEmailWrongCode() throws Exception { .andExpect(status().is(422)); // Wrong audience - String code = externalTokenService.createToken( + String code = greenTokenService.createToken( "", // blank audience Long.toString(UNVERIFIED_USER_ID), 60000L, LecUtils.mapOf("newEmail", NEW_EMAIL)); @@ -88,8 +88,8 @@ public void testChangeEmailWrongCode() throws Exception { .andExpect(status().is(401)); // Wrong userId subject - code = externalTokenService.createToken( - ExternalTokenService.CHANGE_EMAIL_AUDIENCE, + code = greenTokenService.createToken( + GreenTokenService.CHANGE_EMAIL_AUDIENCE, Long.toString(ADMIN_ID), 60000L, LecUtils.mapOf("newEmail", NEW_EMAIL)); @@ -100,8 +100,8 @@ public void testChangeEmailWrongCode() throws Exception { .andExpect(status().is(403)); // Wrong new email - code = externalTokenService.createToken( - ExternalTokenService.CHANGE_EMAIL_AUDIENCE, + code = greenTokenService.createToken( + GreenTokenService.CHANGE_EMAIL_AUDIENCE, Long.toString(UNVERIFIED_USER_ID), 60000L, LecUtils.mapOf("newEmail", "wrong.new.email@example.com")); diff --git a/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/ResetPasswordMvcTests.java b/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/ResetPasswordMvcTests.java index 9456b9c5..f332e8a4 100644 --- a/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/ResetPasswordMvcTests.java +++ b/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/ResetPasswordMvcTests.java @@ -13,7 +13,7 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.naturalprogrammer.spring.lemon.commons.domain.ResetPasswordForm; -import com.naturalprogrammer.spring.lemon.commons.security.ExternalTokenService; +import com.naturalprogrammer.spring.lemon.commons.security.GreenTokenService; import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; public class ResetPasswordMvcTests extends AbstractMvcTests { @@ -21,13 +21,13 @@ public class ResetPasswordMvcTests extends AbstractMvcTests { private String forgotPasswordCode; @Autowired - private ExternalTokenService externalTokenService; + private GreenTokenService greenTokenService; @Before public void setUp() { - forgotPasswordCode = externalTokenService.createToken( - ExternalTokenService.FORGOT_PASSWORD_AUDIENCE, + forgotPasswordCode = greenTokenService.createToken( + GreenTokenService.FORGOT_PASSWORD_AUDIENCE, ADMIN_EMAIL, 60000L); } diff --git a/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/VerificationMvcTests.java b/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/VerificationMvcTests.java index de24c54b..53ef2a61 100644 --- a/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/VerificationMvcTests.java +++ b/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/VerificationMvcTests.java @@ -12,7 +12,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.MediaType; -import com.naturalprogrammer.spring.lemon.commons.security.ExternalTokenService; +import com.naturalprogrammer.spring.lemon.commons.security.GreenTokenService; import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; import com.naturalprogrammer.spring.lemondemo.entities.User; @@ -21,12 +21,12 @@ public class VerificationMvcTests extends AbstractMvcTests { private String verificationCode; @Autowired - private ExternalTokenService externalTokenService; + private GreenTokenService greenTokenService; @Before public void setUp() { - verificationCode = externalTokenService.createToken(ExternalTokenService.VERIFY_AUDIENCE, + verificationCode = greenTokenService.createToken(GreenTokenService.VERIFY_AUDIENCE, Long.toString(UNVERIFIED_USER_ID), 60000L, LecUtils.mapOf("email", UNVERIFIED_USER_EMAIL)); } @@ -75,7 +75,7 @@ public void testEmailVerificationWrongToken() throws Exception { .andExpect(status().is(401)); // Wrong audience - String token = externalTokenService.createToken("wrong-audience", + String token = greenTokenService.createToken("wrong-audience", Long.toString(UNVERIFIED_USER_ID), 60000L, LecUtils.mapOf("email", UNVERIFIED_USER_EMAIL)); mvc.perform(post("/api/core/users/{userId}/verification", UNVERIFIED_USER_ID) @@ -84,7 +84,7 @@ public void testEmailVerificationWrongToken() throws Exception { .andExpect(status().is(401)); // Wrong email - token = externalTokenService.createToken(ExternalTokenService.VERIFY_AUDIENCE, + token = greenTokenService.createToken(GreenTokenService.VERIFY_AUDIENCE, Long.toString(UNVERIFIED_USER_ID), 60000L, LecUtils.mapOf("email", "wrong.email@example.com")); mvc.perform(post("/api/core/users/{userId}/verification", UNVERIFIED_USER_ID) @@ -93,7 +93,7 @@ public void testEmailVerificationWrongToken() throws Exception { .andExpect(status().is(403)); // expired token - token = externalTokenService.createToken(ExternalTokenService.VERIFY_AUDIENCE, + token = greenTokenService.createToken(GreenTokenService.VERIFY_AUDIENCE, Long.toString(UNVERIFIED_USER_ID), 1L, LecUtils.mapOf("email", UNVERIFIED_USER_EMAIL)); // Thread.sleep(1001L); diff --git a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/ChangeEmailTests.java b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/ChangeEmailTests.java index c0b58d23..3d2e7806 100644 --- a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/ChangeEmailTests.java +++ b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/ChangeEmailTests.java @@ -18,7 +18,7 @@ import org.springframework.http.HttpStatus; import org.springframework.test.web.reactive.server.WebTestClient.ResponseSpec; -import com.naturalprogrammer.spring.lemon.commons.security.ExternalTokenService; +import com.naturalprogrammer.spring.lemon.commons.security.GreenTokenService; import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; import com.naturalprogrammer.spring.lemondemo.domain.User; @@ -29,7 +29,7 @@ public class ChangeEmailTests extends AbstractTests { private String changeEmailCode; @Autowired - private ExternalTokenService externalTokenService; + private GreenTokenService greenTokenService; @Before public void setUp() { @@ -38,8 +38,8 @@ public void setUp() { user.setNewEmail(NEW_EMAIL); mongoTemplate.save(user); - changeEmailCode = externalTokenService.createToken( - ExternalTokenService.CHANGE_EMAIL_AUDIENCE, + changeEmailCode = greenTokenService.createToken( + GreenTokenService.CHANGE_EMAIL_AUDIENCE, UNVERIFIED_USER_ID.toString(), 60000L, LecUtils.mapOf("newEmail", NEW_EMAIL)); } @@ -71,7 +71,7 @@ public void testChangeEmailWrongCode() throws Exception { .expectStatus().isEqualTo(HttpStatus.UNPROCESSABLE_ENTITY); // Wrong audience - String code = externalTokenService.createToken( + String code = greenTokenService.createToken( "", // blank audience UNVERIFIED_USER_ID.toString(), 60000L, LecUtils.mapOf("newEmail", NEW_EMAIL)); @@ -80,8 +80,8 @@ public void testChangeEmailWrongCode() throws Exception { .expectStatus().isUnauthorized(); // Wrong userId subject - code = externalTokenService.createToken( - ExternalTokenService.CHANGE_EMAIL_AUDIENCE, + code = greenTokenService.createToken( + GreenTokenService.CHANGE_EMAIL_AUDIENCE, ADMIN_ID.toString(), 60000L, LecUtils.mapOf("newEmail", NEW_EMAIL)); @@ -89,8 +89,8 @@ public void testChangeEmailWrongCode() throws Exception { .expectStatus().isForbidden(); // Wrong new email - code = externalTokenService.createToken( - ExternalTokenService.CHANGE_EMAIL_AUDIENCE, + code = greenTokenService.createToken( + GreenTokenService.CHANGE_EMAIL_AUDIENCE, UNVERIFIED_USER_ID.toString(), 60000L, LecUtils.mapOf("newEmail", "wrong.new.email@example.com")); diff --git a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/ResetPasswordTests.java b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/ResetPasswordTests.java index d49c64f8..47dc69e4 100644 --- a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/ResetPasswordTests.java +++ b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/ResetPasswordTests.java @@ -12,7 +12,7 @@ import org.springframework.http.MediaType; import org.springframework.test.web.reactive.server.WebTestClient.ResponseSpec; -import com.naturalprogrammer.spring.lemon.commons.security.ExternalTokenService; +import com.naturalprogrammer.spring.lemon.commons.security.GreenTokenService; import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; import com.naturalprogrammer.spring.lemondemo.dto.TestResetPasswordForm; @@ -23,13 +23,13 @@ public class ResetPasswordTests extends AbstractTests { private String forgotPasswordCode; @Autowired - private ExternalTokenService externalTokenService; + private GreenTokenService greenTokenService; @Before public void setUp() { - forgotPasswordCode = externalTokenService.createToken( - ExternalTokenService.FORGOT_PASSWORD_AUDIENCE, + forgotPasswordCode = greenTokenService.createToken( + GreenTokenService.FORGOT_PASSWORD_AUDIENCE, ADMIN_EMAIL, 60000L); } diff --git a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/VerificationTests.java b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/VerificationTests.java index 4bd5e25b..30b3a4bc 100644 --- a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/VerificationTests.java +++ b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/VerificationTests.java @@ -16,7 +16,7 @@ import org.springframework.http.HttpStatus; import org.springframework.test.web.reactive.server.WebTestClient.ResponseSpec; -import com.naturalprogrammer.spring.lemon.commons.security.ExternalTokenService; +import com.naturalprogrammer.spring.lemon.commons.security.GreenTokenService; import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; import com.naturalprogrammer.spring.lemondemo.dto.TestUserDto; @@ -25,12 +25,12 @@ public class VerificationTests extends AbstractTests { private String verificationCode; @Autowired - private ExternalTokenService externalTokenService; + private GreenTokenService greenTokenService; @Before public void setUp() { - verificationCode = externalTokenService.createToken(ExternalTokenService.VERIFY_AUDIENCE, + verificationCode = greenTokenService.createToken(GreenTokenService.VERIFY_AUDIENCE, UNVERIFIED_USER_ID.toString(), 60000L, LecUtils.mapOf("email", UNVERIFIED_USER_EMAIL)); } @@ -77,21 +77,21 @@ public void testEmailVerificationWrongToken() throws Exception { .expectStatus().isEqualTo(HttpStatus.UNPROCESSABLE_ENTITY); // Wrong audience - String token = externalTokenService.createToken("wrong-audience", + String token = greenTokenService.createToken("wrong-audience", UNVERIFIED_USER_ID.toString(), 60000L, LecUtils.mapOf("email", UNVERIFIED_USER_EMAIL)); emailVerification(UNVERIFIED_USER_ID, token) .expectStatus().isUnauthorized(); // Wrong email - token = externalTokenService.createToken(ExternalTokenService.VERIFY_AUDIENCE, + token = greenTokenService.createToken(GreenTokenService.VERIFY_AUDIENCE, UNVERIFIED_USER_ID.toString(), 60000L, LecUtils.mapOf("email", "wrong.email@example.com")); emailVerification(UNVERIFIED_USER_ID, token) .expectStatus().isForbidden(); // expired token - token = externalTokenService.createToken(ExternalTokenService.VERIFY_AUDIENCE, + token = greenTokenService.createToken(GreenTokenService.VERIFY_AUDIENCE, UNVERIFIED_USER_ID.toString(), 1L, LecUtils.mapOf("email", UNVERIFIED_USER_EMAIL)); emailVerification(UNVERIFIED_USER_ID, token) diff --git a/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/LemonCommonsReactiveAutoConfiguration.java b/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/LemonCommonsReactiveAutoConfiguration.java index 63c05677..462f6793 100644 --- a/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/LemonCommonsReactiveAutoConfiguration.java +++ b/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/LemonCommonsReactiveAutoConfiguration.java @@ -26,7 +26,7 @@ import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; import com.naturalprogrammer.spring.lemon.commons.LemonCommonsAutoConfiguration; import com.naturalprogrammer.spring.lemon.commons.LemonProperties; -import com.naturalprogrammer.spring.lemon.commons.security.AuthTokenService; +import com.naturalprogrammer.spring.lemon.commons.security.BlueTokenService; import com.naturalprogrammer.spring.lemon.commonsreactive.exceptions.LemonReactiveErrorAttributes; import com.naturalprogrammer.spring.lemon.commonsreactive.exceptions.handlers.VersionExceptionHandler; import com.naturalprogrammer.spring.lemon.commonsreactive.security.LemonCommonsReactiveSecurityConfig; @@ -68,10 +68,10 @@ ErrorAttributes errorAttributes(ErrorResponseComposer errorResponseComposer) @Bean @ConditionalOnMissingBean(LemonCommonsReactiveSecurityConfig.class) - public LemonCommonsReactiveSecurityConfig lemonReactiveSecurityConfig(AuthTokenService authTokenService) { + public LemonCommonsReactiveSecurityConfig lemonReactiveSecurityConfig(BlueTokenService blueTokenService) { log.info("Configuring LemonCommonsReactiveSecurityConfig ..."); - return new LemonCommonsReactiveSecurityConfig(authTokenService); + return new LemonCommonsReactiveSecurityConfig(blueTokenService); } diff --git a/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/security/LemonCommonsReactiveSecurityConfig.java b/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/security/LemonCommonsReactiveSecurityConfig.java index 07df4af6..af24a3a6 100644 --- a/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/security/LemonCommonsReactiveSecurityConfig.java +++ b/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/security/LemonCommonsReactiveSecurityConfig.java @@ -19,7 +19,7 @@ import org.springframework.security.web.server.context.NoOpServerSecurityContextRepository; import org.springframework.web.server.ServerWebExchange; -import com.naturalprogrammer.spring.lemon.commons.security.AuthTokenService; +import com.naturalprogrammer.spring.lemon.commons.security.BlueTokenService; import com.naturalprogrammer.spring.lemon.commons.security.LemonPrincipal; import com.naturalprogrammer.spring.lemon.commons.security.UserDto; import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; @@ -34,7 +34,7 @@ public class LemonCommonsReactiveSecurityConfig { private static final Log log = LogFactory.getLog(LemonCommonsReactiveSecurityConfig.class); - protected AuthTokenService authTokenService; + protected BlueTokenService blueTokenService; public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) { @@ -91,7 +91,7 @@ protected ReactiveAuthenticationManager tokenAuthenticationManager() { String token = (String) authentication.getCredentials(); - JWTClaimsSet claims = authTokenService.parseToken(token, AuthTokenService.AUTH_AUDIENCE); + JWTClaimsSet claims = blueTokenService.parseToken(token, BlueTokenService.AUTH_AUDIENCE); UserDto userDto = LecUtils.getUserDto(claims); diff --git a/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/security/LemonCommonsWebTokenAuthenticationFilter.java b/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/security/LemonCommonsWebTokenAuthenticationFilter.java index 033781f4..7b14c69b 100644 --- a/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/security/LemonCommonsWebTokenAuthenticationFilter.java +++ b/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/security/LemonCommonsWebTokenAuthenticationFilter.java @@ -16,7 +16,7 @@ import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.web.filter.OncePerRequestFilter; -import com.naturalprogrammer.spring.lemon.commons.security.AuthTokenService; +import com.naturalprogrammer.spring.lemon.commons.security.BlueTokenService; import com.naturalprogrammer.spring.lemon.commons.security.LemonPrincipal; import com.naturalprogrammer.spring.lemon.commons.security.UserDto; import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; @@ -33,7 +33,7 @@ public class LemonCommonsWebTokenAuthenticationFilter extends OncePerRequestFilt private static final Log log = LogFactory.getLog(LemonCommonsWebTokenAuthenticationFilter.class); - private AuthTokenService authTokenService; + private BlueTokenService blueTokenService; @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) @@ -74,7 +74,7 @@ protected void doFilterInternal(HttpServletRequest request, HttpServletResponse protected Authentication createAuthToken(String token) { - JWTClaimsSet claims = authTokenService.parseToken(token, AuthTokenService.AUTH_AUDIENCE); + JWTClaimsSet claims = blueTokenService.parseToken(token, BlueTokenService.AUTH_AUDIENCE); UserDto userDto = LecUtils.getUserDto(claims); if (userDto == null) userDto = fetchUserDto(claims); diff --git a/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/security/LemonWebSecurityConfig.java b/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/security/LemonWebSecurityConfig.java index 027fb017..2b9c9f26 100644 --- a/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/security/LemonWebSecurityConfig.java +++ b/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/security/LemonWebSecurityConfig.java @@ -9,7 +9,7 @@ import org.springframework.security.web.authentication.Http403ForbiddenEntryPoint; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; -import com.naturalprogrammer.spring.lemon.commons.security.AuthTokenService; +import com.naturalprogrammer.spring.lemon.commons.security.BlueTokenService; /** * Security configuration class. Extend it in the @@ -22,12 +22,12 @@ public class LemonWebSecurityConfig extends WebSecurityConfigurerAdapter { private static final Log log = LogFactory.getLog(LemonWebSecurityConfig.class); - protected AuthTokenService authTokenService; + protected BlueTokenService blueTokenService; @Autowired - public void createLemonWebSecurityConfig(AuthTokenService authTokenService) { + public void createLemonWebSecurityConfig(BlueTokenService blueTokenService) { - this.authTokenService = authTokenService; + this.blueTokenService = blueTokenService; log.info("Created"); } @@ -90,7 +90,7 @@ protected void exceptionHandling(HttpSecurity http) throws Exception { */ protected void tokenAuthentication(HttpSecurity http) throws Exception { - http.addFilterBefore(new LemonCommonsWebTokenAuthenticationFilter(authTokenService), + http.addFilterBefore(new LemonCommonsWebTokenAuthenticationFilter(blueTokenService), UsernamePasswordAuthenticationFilter.class); } diff --git a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/LemonCommonsAutoConfiguration.java b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/LemonCommonsAutoConfiguration.java index e0854272..2ac33881 100644 --- a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/LemonCommonsAutoConfiguration.java +++ b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/LemonCommonsAutoConfiguration.java @@ -21,8 +21,8 @@ import com.naturalprogrammer.spring.lemon.commons.mail.MailSender; import com.naturalprogrammer.spring.lemon.commons.mail.MockMailSender; import com.naturalprogrammer.spring.lemon.commons.mail.SmtpMailSender; -import com.naturalprogrammer.spring.lemon.commons.security.AuthTokenService; -import com.naturalprogrammer.spring.lemon.commons.security.ExternalTokenService; +import com.naturalprogrammer.spring.lemon.commons.security.BlueTokenService; +import com.naturalprogrammer.spring.lemon.commons.security.GreenTokenService; import com.naturalprogrammer.spring.lemon.commons.security.LemonJweService; import com.naturalprogrammer.spring.lemon.commons.security.LemonJwsService; import com.naturalprogrammer.spring.lemon.commons.security.LemonPermissionEvaluator; @@ -61,8 +61,8 @@ public LemonProperties lemonProperties() { * Configures AuthTokenService if missing */ @Bean - @ConditionalOnMissingBean(AuthTokenService.class) - public AuthTokenService authTokenService(LemonProperties properties) throws JOSEException { + @ConditionalOnMissingBean(BlueTokenService.class) + public BlueTokenService blueTokenService(LemonProperties properties) throws JOSEException { log.info("Configuring AuthTokenService"); return new LemonJwsService(properties.getJwt().getSecret()); @@ -73,8 +73,8 @@ public AuthTokenService authTokenService(LemonProperties properties) throws JOSE * Configures ExternalTokenService if missing */ @Bean - @ConditionalOnMissingBean(ExternalTokenService.class) - public ExternalTokenService externalTokenService(LemonProperties properties) throws KeyLengthException { + @ConditionalOnMissingBean(GreenTokenService.class) + public GreenTokenService greenTokenService(LemonProperties properties) throws KeyLengthException { log.info("Configuring ExternalTokenService"); return new LemonJweService(properties.getJwt().getSecret()); diff --git a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/AuthTokenService.java b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/BlueTokenService.java similarity index 64% rename from spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/AuthTokenService.java rename to spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/BlueTokenService.java index 9fcaaaff..36734a78 100644 --- a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/AuthTokenService.java +++ b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/BlueTokenService.java @@ -1,6 +1,6 @@ package com.naturalprogrammer.spring.lemon.commons.security; -public interface AuthTokenService extends LemonTokenService { +public interface BlueTokenService extends LemonTokenService { String USER_CLAIM = "user"; String AUTH_AUDIENCE = "auth"; diff --git a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/ExternalTokenService.java b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/GreenTokenService.java similarity index 73% rename from spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/ExternalTokenService.java rename to spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/GreenTokenService.java index b82ae6ec..3d515b3d 100644 --- a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/ExternalTokenService.java +++ b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/GreenTokenService.java @@ -1,6 +1,6 @@ package com.naturalprogrammer.spring.lemon.commons.security; -public interface ExternalTokenService extends LemonTokenService { +public interface GreenTokenService extends LemonTokenService { String VERIFY_AUDIENCE = "verify"; String FORGOT_PASSWORD_AUDIENCE = "forgot-password"; diff --git a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/LemonJweService.java b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/LemonJweService.java index 28f82a8f..2fa730ef 100644 --- a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/LemonJweService.java +++ b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/LemonJweService.java @@ -33,7 +33,7 @@ * https://connect2id.com/products/nimbus-jose-jwt/examples/jwe-with-shared-key * https://connect2id.com/products/nimbus-jose-jwt/examples/validating-jwt-access-tokens */ -public class LemonJweService extends AbstractJwtService implements ExternalTokenService { +public class LemonJweService extends AbstractJwtService implements GreenTokenService { private static final Log log = LogFactory.getLog(LemonJweService.class); diff --git a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/LemonJwsService.java b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/LemonJwsService.java index 5de00802..d6680adb 100644 --- a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/LemonJwsService.java +++ b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/LemonJwsService.java @@ -21,7 +21,7 @@ * * Reference: https://connect2id.com/products/nimbus-jose-jwt/examples/jws-with-hmac */ -public class LemonJwsService extends AbstractJwtService implements AuthTokenService { +public class LemonJwsService extends AbstractJwtService implements BlueTokenService { private JWSSigner signer; private JWSVerifier verifier; diff --git a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/util/LecUtils.java b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/util/LecUtils.java index 35ee010f..3c3b1ed3 100644 --- a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/util/LecUtils.java +++ b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/util/LecUtils.java @@ -25,7 +25,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.github.fge.jsonpatch.JsonPatch; import com.github.fge.jsonpatch.JsonPatchException; -import com.naturalprogrammer.spring.lemon.commons.security.AuthTokenService; +import com.naturalprogrammer.spring.lemon.commons.security.BlueTokenService; import com.naturalprogrammer.spring.lemon.commons.security.LemonPrincipal; import com.naturalprogrammer.spring.lemon.commons.security.UserDto; import com.naturalprogrammer.spring.lemon.exceptions.util.LexUtils; @@ -255,7 +255,7 @@ public static T deserialize(String serializedObj) { public static UserDto getUserDto(JWTClaimsSet claims) { - Object userClaim = claims.getClaim(AuthTokenService.USER_CLAIM); + Object userClaim = claims.getClaim(BlueTokenService.USER_CLAIM); if (userClaim == null) return null; diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/LemonAutoConfiguration.java b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/LemonAutoConfiguration.java index 156d069d..6937e280 100644 --- a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/LemonAutoConfiguration.java +++ b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/LemonAutoConfiguration.java @@ -19,7 +19,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.naturalprogrammer.spring.lemon.commons.LemonProperties; import com.naturalprogrammer.spring.lemon.commons.domain.IdConverter; -import com.naturalprogrammer.spring.lemon.commons.security.AuthTokenService; +import com.naturalprogrammer.spring.lemon.commons.security.BlueTokenService; import com.naturalprogrammer.spring.lemon.commons.validation.RetypePasswordValidator; import com.naturalprogrammer.spring.lemon.commonsjpa.LemonCommonsJpaAutoConfiguration; import com.naturalprogrammer.spring.lemon.commonsweb.security.LemonWebSecurityConfig; @@ -77,10 +77,10 @@ public LemonAuthenticationSuccessHandler authenticationSuccessHandler( @Bean @ConditionalOnMissingBean(OAuth2AuthenticationSuccessHandler.class) public OAuth2AuthenticationSuccessHandler oauth2AuthenticationSuccessHandler( - LemonProperties properties, AuthTokenService authTokenService) { + LemonProperties properties, BlueTokenService blueTokenService) { log.info("Configuring OAuth2AuthenticationSuccessHandler"); - return new OAuth2AuthenticationSuccessHandler<>(properties, authTokenService); + return new OAuth2AuthenticationSuccessHandler<>(properties, blueTokenService); } /** diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/LemonService.java b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/LemonService.java index 2368b1c3..849f34aa 100644 --- a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/LemonService.java +++ b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/LemonService.java @@ -33,8 +33,8 @@ import com.naturalprogrammer.spring.lemon.commons.domain.ResetPasswordForm; import com.naturalprogrammer.spring.lemon.commons.mail.LemonMailData; import com.naturalprogrammer.spring.lemon.commons.mail.MailSender; -import com.naturalprogrammer.spring.lemon.commons.security.AuthTokenService; -import com.naturalprogrammer.spring.lemon.commons.security.ExternalTokenService; +import com.naturalprogrammer.spring.lemon.commons.security.BlueTokenService; +import com.naturalprogrammer.spring.lemon.commons.security.GreenTokenService; import com.naturalprogrammer.spring.lemon.commons.security.UserDto; import com.naturalprogrammer.spring.lemon.commons.security.UserEditPermission; import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; @@ -64,8 +64,8 @@ public abstract class LemonService private MailSender mailSender; private AbstractUserRepository userRepository; private UserDetailsService userDetailsService; - private AuthTokenService authTokenService; - private ExternalTokenService externalTokenService; + private BlueTokenService blueTokenService; + private GreenTokenService greenTokenService; @Autowired public void createLemonService(LemonProperties properties, @@ -73,16 +73,16 @@ public void createLemonService(LemonProperties properties, MailSender mailSender, AbstractUserRepository userRepository, UserDetailsService userDetailsService, - AuthTokenService authTokenService, - ExternalTokenService externalTokenService) { + BlueTokenService blueTokenService, + GreenTokenService greenTokenService) { this.properties = properties; this.passwordEncoder = passwordEncoder; this.mailSender = mailSender; this.userRepository = userRepository; this.userDetailsService = userDetailsService; - this.authTokenService = authTokenService; - this.externalTokenService = externalTokenService; + this.blueTokenService = blueTokenService; + this.greenTokenService = greenTokenService; log.info("Created"); } @@ -247,8 +247,8 @@ protected void sendVerificationMail(final U user) { log.debug("Sending verification mail to: " + user); - String verificationCode = externalTokenService.createToken( - ExternalTokenService.VERIFY_AUDIENCE, + String verificationCode = greenTokenService.createToken( + GreenTokenService.VERIFY_AUDIENCE, user.getId().toString(), properties.getJwt().getExpirationMillis(), LecUtils.mapOf("email", user.getEmail())); @@ -341,8 +341,8 @@ public void verifyUser(ID userId, String verificationCode) { LexUtils.validate(user.hasRole(UserUtils.Role.UNVERIFIED), "com.naturalprogrammer.spring.alreadyVerified").go(); - JWTClaimsSet claims = externalTokenService.parseToken(verificationCode, - ExternalTokenService.VERIFY_AUDIENCE, user.getCredentialsUpdatedMillis()); + JWTClaimsSet claims = greenTokenService.parseToken(verificationCode, + GreenTokenService.VERIFY_AUDIENCE, user.getCredentialsUpdatedMillis()); LecUtils.ensureAuthority( claims.getSubject().equals(user.getId().toString()) && @@ -390,8 +390,8 @@ public void mailForgotPasswordLink(U user) { log.debug("Mailing forgot password link to user: " + user); - String forgotPasswordCode = externalTokenService.createToken( - ExternalTokenService.FORGOT_PASSWORD_AUDIENCE, + String forgotPasswordCode = greenTokenService.createToken( + GreenTokenService.FORGOT_PASSWORD_AUDIENCE, user.getEmail(), properties.getJwt().getExpirationMillis()); // make the link @@ -426,8 +426,8 @@ public void resetPassword(@Valid ResetPasswordForm form) { log.debug("Resetting password ..."); - JWTClaimsSet claims = externalTokenService.parseToken(form.getCode(), - ExternalTokenService.FORGOT_PASSWORD_AUDIENCE); + JWTClaimsSet claims = greenTokenService.parseToken(form.getCode(), + GreenTokenService.FORGOT_PASSWORD_AUDIENCE); String email = claims.getSubject(); @@ -581,8 +581,8 @@ public void requestEmailChange(U user, @Valid U updatedUser) { */ protected void mailChangeEmailLink(U user) { - String changeEmailCode = externalTokenService.createToken( - ExternalTokenService.CHANGE_EMAIL_AUDIENCE, + String changeEmailCode = greenTokenService.createToken( + GreenTokenService.CHANGE_EMAIL_AUDIENCE, user.getId().toString(), properties.getJwt().getExpirationMillis(), LecUtils.mapOf("newEmail", user.getNewEmail())); @@ -643,8 +643,8 @@ public void changeEmail(ID userId, @Valid @NotBlank String changeEmailCode) { LexUtils.validate(StringUtils.isNotBlank(user.getNewEmail()), "com.naturalprogrammer.spring.blank.newEmail").go(); - JWTClaimsSet claims = externalTokenService.parseToken(changeEmailCode, - ExternalTokenService.CHANGE_EMAIL_AUDIENCE, + JWTClaimsSet claims = greenTokenService.parseToken(changeEmailCode, + GreenTokenService.CHANGE_EMAIL_AUDIENCE, user.getCredentialsUpdatedMillis()); LecUtils.ensureAuthority( @@ -727,7 +727,7 @@ public String fetchNewToken(Optional expirationMillis, currentUser.isGoodAdmin(), "com.naturalprogrammer.spring.notGoodAdminOrSameUser"); return LecUtils.TOKEN_PREFIX + - authTokenService.createToken(AuthTokenService.AUTH_AUDIENCE, username, + blueTokenService.createToken(BlueTokenService.AUTH_AUDIENCE, username, expirationMillis.orElse(properties.getJwt().getExpirationMillis())); } @@ -759,16 +759,16 @@ protected void hideConfidentialFields(U user) { @PreAuthorize("isAuthenticated()") public Map fetchFullToken(String authHeader) { - LecUtils.ensureCredentials(authTokenService.parseClaim(authHeader.substring(LecUtils.TOKEN_PREFIX_LENGTH), - AuthTokenService.USER_CLAIM) == null, "com.naturalprogrammer.spring.fullTokenNotAllowed"); + LecUtils.ensureCredentials(blueTokenService.parseClaim(authHeader.substring(LecUtils.TOKEN_PREFIX_LENGTH), + BlueTokenService.USER_CLAIM) == null, "com.naturalprogrammer.spring.fullTokenNotAllowed"); UserDto currentUser = LecwUtils.currentUser(); - Map claimMap = Collections.singletonMap(AuthTokenService.USER_CLAIM, + Map claimMap = Collections.singletonMap(BlueTokenService.USER_CLAIM, LecUtils.serialize(currentUser)); // Not serializing converts it to a JsonNode Map tokenMap = Collections.singletonMap("token", LecUtils.TOKEN_PREFIX + - authTokenService.createToken(AuthTokenService.AUTH_AUDIENCE, currentUser.getUsername(), + blueTokenService.createToken(BlueTokenService.AUTH_AUDIENCE, currentUser.getUsername(), Long.valueOf(properties.getJwt().getShortLivedMillis()), claimMap)); @@ -782,7 +782,7 @@ public Map fetchFullToken(String authHeader) { public void addAuthHeader(HttpServletResponse response, String username, Long expirationMillis) { response.addHeader(LecUtils.TOKEN_RESPONSE_HEADER_NAME, LecUtils.TOKEN_PREFIX + - authTokenService.createToken(AuthTokenService.AUTH_AUDIENCE, username, expirationMillis)); + blueTokenService.createToken(BlueTokenService.AUTH_AUDIENCE, username, expirationMillis)); } diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonJpaSecurityConfig.java b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonJpaSecurityConfig.java index 16354a9c..a8087272 100644 --- a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonJpaSecurityConfig.java +++ b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonJpaSecurityConfig.java @@ -118,7 +118,7 @@ protected void oauth2Client(HttpSecurity http) throws Exception { */ protected void tokenAuthentication(HttpSecurity http) throws Exception { - http.addFilterBefore(new LemonJpaTokenAuthenticationFilter(authTokenService, userDetailsService), + http.addFilterBefore(new LemonJpaTokenAuthenticationFilter(blueTokenService, userDetailsService), UsernamePasswordAuthenticationFilter.class); } } diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonJpaTokenAuthenticationFilter.java b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonJpaTokenAuthenticationFilter.java index 866378e7..49c6b840 100644 --- a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonJpaTokenAuthenticationFilter.java +++ b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonJpaTokenAuthenticationFilter.java @@ -6,7 +6,7 @@ import org.apache.commons.logging.LogFactory; import org.springframework.security.core.userdetails.UsernameNotFoundException; -import com.naturalprogrammer.spring.lemon.commons.security.AuthTokenService; +import com.naturalprogrammer.spring.lemon.commons.security.BlueTokenService; import com.naturalprogrammer.spring.lemon.commons.security.UserDto; import com.naturalprogrammer.spring.lemon.commonsweb.security.LemonCommonsWebTokenAuthenticationFilter; import com.naturalprogrammer.spring.lemon.domain.AbstractUser; @@ -20,10 +20,10 @@ public class LemonJpaTokenAuthenticationFilter, ID ex private LemonUserDetailsService userDetailsService; - public LemonJpaTokenAuthenticationFilter(AuthTokenService authTokenService, + public LemonJpaTokenAuthenticationFilter(BlueTokenService blueTokenService, LemonUserDetailsService userDetailsService) { - super(authTokenService); + super(blueTokenService); this.userDetailsService = userDetailsService; log.info("Created"); diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/OAuth2AuthenticationSuccessHandler.java b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/OAuth2AuthenticationSuccessHandler.java index f88a0b08..bcd609c3 100644 --- a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/OAuth2AuthenticationSuccessHandler.java +++ b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/OAuth2AuthenticationSuccessHandler.java @@ -11,7 +11,7 @@ import org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler; import com.naturalprogrammer.spring.lemon.commons.LemonProperties; -import com.naturalprogrammer.spring.lemon.commons.security.AuthTokenService; +import com.naturalprogrammer.spring.lemon.commons.security.BlueTokenService; import com.naturalprogrammer.spring.lemon.commons.security.UserDto; import com.naturalprogrammer.spring.lemon.commonsweb.util.LecwUtils; @@ -30,7 +30,7 @@ public class OAuth2AuthenticationSuccessHandler private static final Log log = LogFactory.getLog(OAuth2AuthenticationSuccessHandler.class); private LemonProperties properties; - private AuthTokenService authTokenService; + private BlueTokenService blueTokenService; @Override protected String determineTargetUrl(HttpServletRequest request, @@ -38,8 +38,8 @@ protected String determineTargetUrl(HttpServletRequest request, UserDto currentUser = LecwUtils.currentUser(); - String shortLivedAuthToken = authTokenService.createToken( - AuthTokenService.AUTH_AUDIENCE, + String shortLivedAuthToken = blueTokenService.createToken( + BlueTokenService.AUTH_AUDIENCE, currentUser.getUsername(), (long) properties.getJwt().getShortLivedMillis()); diff --git a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveAutoConfiguration.java b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveAutoConfiguration.java index bfaee84f..8bd2dc7a 100644 --- a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveAutoConfiguration.java +++ b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveAutoConfiguration.java @@ -12,7 +12,7 @@ import org.springframework.security.core.userdetails.UserDetailsService; import com.naturalprogrammer.spring.lemon.commons.domain.IdConverter; -import com.naturalprogrammer.spring.lemon.commons.security.AuthTokenService; +import com.naturalprogrammer.spring.lemon.commons.security.BlueTokenService; import com.naturalprogrammer.spring.lemon.commonsmongo.LemonCommonsMongoAutoConfiguration; import com.naturalprogrammer.spring.lemon.exceptions.util.LexUtils; import com.naturalprogrammer.spring.lemonreactive.domain.AbstractMongoUser; @@ -44,12 +44,12 @@ IdConverter idConverter(LemonReactiveService lemonService) { @ConditionalOnMissingBean(LemonReactiveSecurityConfig.class) public , ID extends Serializable> LemonReactiveSecurityConfig lemonReactiveSecurityConfig( - AuthTokenService authTokenService, + BlueTokenService blueTokenService, LemonReactiveUserDetailsService userDetailsService) { log.info("Configuring LemonReactiveSecurityConfig ..."); - return new LemonReactiveSecurityConfig(authTokenService, userDetailsService); + return new LemonReactiveSecurityConfig(blueTokenService, userDetailsService); } diff --git a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveService.java b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveService.java index 33c46e25..3c91aa0d 100644 --- a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveService.java +++ b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveService.java @@ -27,8 +27,8 @@ import com.naturalprogrammer.spring.lemon.commons.domain.ResetPasswordForm; import com.naturalprogrammer.spring.lemon.commons.mail.LemonMailData; import com.naturalprogrammer.spring.lemon.commons.mail.MailSender; -import com.naturalprogrammer.spring.lemon.commons.security.AuthTokenService; -import com.naturalprogrammer.spring.lemon.commons.security.ExternalTokenService; +import com.naturalprogrammer.spring.lemon.commons.security.BlueTokenService; +import com.naturalprogrammer.spring.lemon.commons.security.GreenTokenService; import com.naturalprogrammer.spring.lemon.commons.security.UserDto; import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; import com.naturalprogrammer.spring.lemon.commons.util.UserUtils; @@ -56,8 +56,8 @@ public abstract class LemonReactiveService protected MailSender mailSender; protected AbstractMongoUserRepository userRepository; protected ReactiveUserDetailsService userDetailsService; - protected AuthTokenService authTokenService; - protected ExternalTokenService externalTokenService; + protected BlueTokenService blueTokenService; + protected GreenTokenService greenTokenService; @Autowired public void createLemonService(LemonProperties properties, @@ -65,16 +65,16 @@ public void createLemonService(LemonProperties properties, MailSender mailSender, AbstractMongoUserRepository userRepository, ReactiveUserDetailsService userDetailsService, - AuthTokenService authTokenService, - ExternalTokenService externalTokenService) { + BlueTokenService blueTokenService, + GreenTokenService greenTokenService) { this.properties = properties; this.passwordEncoder = passwordEncoder; this.mailSender = mailSender; this.userRepository = userRepository; this.userDetailsService = userDetailsService; - this.authTokenService = authTokenService; - this.externalTokenService = externalTokenService; + this.blueTokenService = blueTokenService; + this.greenTokenService = greenTokenService; log.info("Created"); } @@ -236,7 +236,7 @@ protected void sendVerificationMail(final U user) { log.debug("Sending verification mail to: " + user); - String verificationCode = externalTokenService.createToken(ExternalTokenService.VERIFY_AUDIENCE, + String verificationCode = greenTokenService.createToken(GreenTokenService.VERIFY_AUDIENCE, user.getId().toString(), properties.getJwt().getExpirationMillis(), LecUtils.mapOf("email", user.getEmail())); @@ -330,8 +330,8 @@ public U verifyUser(Tuple2> tuple) { LexUtils.validate(user.hasRole(UserUtils.Role.UNVERIFIED), "com.naturalprogrammer.spring.alreadyVerified").go(); - JWTClaimsSet claims = externalTokenService.parseToken( - verificationCode, ExternalTokenService.VERIFY_AUDIENCE, user.getCredentialsUpdatedMillis()); + JWTClaimsSet claims = greenTokenService.parseToken( + verificationCode, GreenTokenService.VERIFY_AUDIENCE, user.getCredentialsUpdatedMillis()); LecUtils.ensureAuthority( claims.getSubject().equals(user.getId().toString()) && @@ -367,8 +367,8 @@ public void mailForgotPasswordLink(U user) { log.debug("Mailing forgot password link to user: " + user); - String forgotPasswordCode = externalTokenService.createToken( - ExternalTokenService.FORGOT_PASSWORD_AUDIENCE, + String forgotPasswordCode = greenTokenService.createToken( + GreenTokenService.FORGOT_PASSWORD_AUDIENCE, user.getEmail(), properties.getJwt().getExpirationMillis()); // make the link @@ -402,8 +402,8 @@ public Mono resetPassword(Mono resetPasswordForm) { log.debug("Resetting password ..."); - JWTClaimsSet claims = externalTokenService.parseToken(form.getCode(), - ExternalTokenService.FORGOT_PASSWORD_AUDIENCE); + JWTClaimsSet claims = greenTokenService.parseToken(form.getCode(), + GreenTokenService.FORGOT_PASSWORD_AUDIENCE); String email = claims.getSubject(); @@ -457,7 +457,7 @@ protected void addAuthHeader(ServerHttpResponse response, UserDto userDto, long log.debug("Adding auth header for " + userDto.getUsername()); response.getHeaders().add(LecUtils.TOKEN_RESPONSE_HEADER_NAME, LecUtils.TOKEN_PREFIX + - authTokenService.createToken(AuthTokenService.AUTH_AUDIENCE, userDto.getUsername(), expirationMillis)); + blueTokenService.createToken(BlueTokenService.AUTH_AUDIENCE, userDto.getUsername(), expirationMillis)); } @@ -665,8 +665,8 @@ protected void requestEmailChange(Tuple3 tuple) { */ protected void mailChangeEmailLink(U user) { - String changeEmailCode = externalTokenService.createToken( - ExternalTokenService.CHANGE_EMAIL_AUDIENCE, + String changeEmailCode = greenTokenService.createToken( + GreenTokenService.CHANGE_EMAIL_AUDIENCE, user.getId().toString(), properties.getJwt().getExpirationMillis(), LecUtils.mapOf("newEmail", user.getNewEmail())); @@ -741,8 +741,8 @@ protected U validateChangeEmail(Tuple2> tuple) LexUtils.validate(StringUtils.isNotBlank(user.getNewEmail()), "com.naturalprogrammer.spring.blank.newEmail").go(); - JWTClaimsSet claims = externalTokenService.parseToken(code, - ExternalTokenService.CHANGE_EMAIL_AUDIENCE, + JWTClaimsSet claims = greenTokenService.parseToken(code, + GreenTokenService.CHANGE_EMAIL_AUDIENCE, user.getCredentialsUpdatedMillis()); LecUtils.ensureAuthority( @@ -794,7 +794,7 @@ public Mono> fetchNewToken(ServerWebExchange exchange) { currentUser.isGoodAdmin(), "com.naturalprogrammer.spring.notGoodAdminOrSameUser"); return Collections.singletonMap("token", LecUtils.TOKEN_PREFIX + - authTokenService.createToken(authTokenService.AUTH_AUDIENCE, username, expirationMillis)); + blueTokenService.createToken(blueTokenService.AUTH_AUDIENCE, username, expirationMillis)); }); } @@ -802,18 +802,18 @@ public Mono> fetchNewToken(ServerWebExchange exchange) { @PreAuthorize("isAuthenticated()") public Mono> fetchFullToken(String authHeader) { - LecUtils.ensureCredentials(authTokenService.parseClaim(authHeader.substring(LecUtils.TOKEN_PREFIX_LENGTH), - AuthTokenService.USER_CLAIM) == null, "com.naturalprogrammer.spring.fullTokenNotAllowed"); + LecUtils.ensureCredentials(blueTokenService.parseClaim(authHeader.substring(LecUtils.TOKEN_PREFIX_LENGTH), + BlueTokenService.USER_CLAIM) == null, "com.naturalprogrammer.spring.fullTokenNotAllowed"); return LecrUtils.currentUser().map(optionalUser -> { UserDto currentUser = optionalUser.get(); - Map claimMap = Collections.singletonMap(AuthTokenService.USER_CLAIM, + Map claimMap = Collections.singletonMap(BlueTokenService.USER_CLAIM, LecUtils.serialize(currentUser)); // Not serializing converts it to a JsonNode Map tokenMap = Collections.singletonMap("token", LecUtils.TOKEN_PREFIX + - authTokenService.createToken(AuthTokenService.AUTH_AUDIENCE, currentUser.getUsername(), + blueTokenService.createToken(BlueTokenService.AUTH_AUDIENCE, currentUser.getUsername(), Long.valueOf(properties.getJwt().getShortLivedMillis()), claimMap)); diff --git a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/security/LemonReactiveSecurityConfig.java b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/security/LemonReactiveSecurityConfig.java index 1a1a68de..09a1b589 100644 --- a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/security/LemonReactiveSecurityConfig.java +++ b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/security/LemonReactiveSecurityConfig.java @@ -8,7 +8,7 @@ import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.security.web.server.authentication.WebFilterChainServerAuthenticationSuccessHandler; -import com.naturalprogrammer.spring.lemon.commons.security.AuthTokenService; +import com.naturalprogrammer.spring.lemon.commons.security.BlueTokenService; import com.naturalprogrammer.spring.lemon.commons.security.UserDto; import com.naturalprogrammer.spring.lemon.commonsreactive.security.LemonCommonsReactiveSecurityConfig; import com.naturalprogrammer.spring.lemonreactive.domain.AbstractMongoUser; @@ -23,10 +23,10 @@ public class LemonReactiveSecurityConfig , ID ex protected LemonReactiveUserDetailsService userDetailsService; - public LemonReactiveSecurityConfig(AuthTokenService authTokenService, + public LemonReactiveSecurityConfig(BlueTokenService blueTokenService, LemonReactiveUserDetailsService userDetailsService) { - super(authTokenService); + super(blueTokenService); this.userDetailsService = userDetailsService; log.info("Created"); } From a624d7f8d193a0c80fe5b1e82d52e2dd4b549b63 Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Sat, 17 Nov 2018 13:55:10 +0530 Subject: [PATCH 078/116] Just trimmed some spaces --- .../spring/lemon/commons/security/LemonJwsService.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/LemonJwsService.java b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/LemonJwsService.java index d6680adb..1c5a80b8 100644 --- a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/LemonJwsService.java +++ b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/LemonJwsService.java @@ -26,8 +26,6 @@ public class LemonJwsService extends AbstractJwtService implements BlueTokenServ private JWSSigner signer; private JWSVerifier verifier; - - public LemonJwsService(String secret) throws JOSEException { byte[] secretKey = secret.getBytes(); From 6076971348a5d1c2c53a29d8d7cffe9dfc0c1f17 Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Sat, 17 Nov 2018 20:01:56 +0530 Subject: [PATCH 079/116] Changed LemonService.getOAuth2AccountVerified to return flse in case of any errors --- .../com/naturalprogrammer/spring/lemon/LemonService.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/LemonService.java b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/LemonService.java index 849f34aa..211e41c9 100644 --- a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/LemonService.java +++ b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/LemonService.java @@ -708,7 +708,11 @@ public boolean getOAuth2AccountVerified(String registrationId, Map Date: Mon, 19 Nov 2018 12:44:57 +0530 Subject: [PATCH 080/116] Moved ensureCorrectVersion from LemonUtils to LecjUtils --- lemon-demo-jpa/pom.xml | 2 +- lemon-demo-reactive/pom.xml | 2 +- pom.xml | 2 +- spring-lemon-commons-jpa/pom.xml | 2 +- .../spring/lemon/commonsjpa/LecjUtils.java | 18 ++++++++++++++++++ spring-lemon-commons-mongo/pom.xml | 2 +- spring-lemon-commons-reactive/pom.xml | 2 +- spring-lemon-commons-web/pom.xml | 2 +- spring-lemon-commons/pom.xml | 2 +- spring-lemon-exceptions/pom.xml | 2 +- spring-lemon-jpa/pom.xml | 2 +- .../spring/lemon/LemonService.java | 2 +- .../spring/lemon/util/LemonUtils.java | 17 ----------------- spring-lemon-reactive/pom.xml | 2 +- 14 files changed, 30 insertions(+), 29 deletions(-) diff --git a/lemon-demo-jpa/pom.xml b/lemon-demo-jpa/pom.xml index feee0969..6cbc7160 100644 --- a/lemon-demo-jpa/pom.xml +++ b/lemon-demo-jpa/pom.xml @@ -14,7 +14,7 @@ com.naturalprogrammer spring-lemon - 1.0.0.M9 + 1.0.0.RC1 diff --git a/lemon-demo-reactive/pom.xml b/lemon-demo-reactive/pom.xml index b3410f7b..3394af7c 100644 --- a/lemon-demo-reactive/pom.xml +++ b/lemon-demo-reactive/pom.xml @@ -13,7 +13,7 @@ com.naturalprogrammer spring-lemon - 1.0.0.M9 + 1.0.0.RC1 diff --git a/pom.xml b/pom.xml index 82377c7b..3b8efa5d 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.naturalprogrammer spring-lemon - 1.0.0.M9 + 1.0.0.RC1 pom spring-lemon diff --git a/spring-lemon-commons-jpa/pom.xml b/spring-lemon-commons-jpa/pom.xml index 13a4d0ed..fdcc7067 100644 --- a/spring-lemon-commons-jpa/pom.xml +++ b/spring-lemon-commons-jpa/pom.xml @@ -13,7 +13,7 @@ com.naturalprogrammer spring-lemon - 1.0.0.M9 + 1.0.0.RC1 diff --git a/spring-lemon-commons-jpa/src/main/java/com/naturalprogrammer/spring/lemon/commonsjpa/LecjUtils.java b/spring-lemon-commons-jpa/src/main/java/com/naturalprogrammer/spring/lemon/commonsjpa/LecjUtils.java index e2d804ee..3f69ff9c 100644 --- a/spring-lemon-commons-jpa/src/main/java/com/naturalprogrammer/spring/lemon/commonsjpa/LecjUtils.java +++ b/spring-lemon-commons-jpa/src/main/java/com/naturalprogrammer/spring/lemon/commonsjpa/LecjUtils.java @@ -1,8 +1,12 @@ package com.naturalprogrammer.spring.lemon.commonsjpa; +import java.io.Serializable; + import org.springframework.transaction.support.TransactionSynchronizationAdapter; import org.springframework.transaction.support.TransactionSynchronizationManager; +import com.naturalprogrammer.spring.lemon.exceptions.VersionException; + public class LecjUtils { /** @@ -23,4 +27,18 @@ public void afterCommit() { }); } + + /** + * Throws a VersionException if the versions of the + * given entities aren't same. + * + * @param original + * @param updated + */ + public static + void ensureCorrectVersion(LemonEntity original, LemonEntity updated) { + + if (original.getVersion() != updated.getVersion()) + throw new VersionException(original.getClass().getSimpleName(), original.getId().toString()); + } } diff --git a/spring-lemon-commons-mongo/pom.xml b/spring-lemon-commons-mongo/pom.xml index 8ec4b49e..4935a65d 100644 --- a/spring-lemon-commons-mongo/pom.xml +++ b/spring-lemon-commons-mongo/pom.xml @@ -13,7 +13,7 @@ com.naturalprogrammer spring-lemon - 1.0.0.M9 + 1.0.0.RC1 diff --git a/spring-lemon-commons-reactive/pom.xml b/spring-lemon-commons-reactive/pom.xml index a045df3c..6b5e6d23 100644 --- a/spring-lemon-commons-reactive/pom.xml +++ b/spring-lemon-commons-reactive/pom.xml @@ -13,7 +13,7 @@ com.naturalprogrammer spring-lemon - 1.0.0.M9 + 1.0.0.RC1 diff --git a/spring-lemon-commons-web/pom.xml b/spring-lemon-commons-web/pom.xml index 2f96fb17..a3b13d72 100644 --- a/spring-lemon-commons-web/pom.xml +++ b/spring-lemon-commons-web/pom.xml @@ -13,7 +13,7 @@ com.naturalprogrammer spring-lemon - 1.0.0.M9 + 1.0.0.RC1 diff --git a/spring-lemon-commons/pom.xml b/spring-lemon-commons/pom.xml index da428087..c680e5e9 100644 --- a/spring-lemon-commons/pom.xml +++ b/spring-lemon-commons/pom.xml @@ -14,7 +14,7 @@ com.naturalprogrammer spring-lemon - 1.0.0.M9 + 1.0.0.RC1 diff --git a/spring-lemon-exceptions/pom.xml b/spring-lemon-exceptions/pom.xml index 316e0d7d..7a64c1e7 100644 --- a/spring-lemon-exceptions/pom.xml +++ b/spring-lemon-exceptions/pom.xml @@ -13,7 +13,7 @@ com.naturalprogrammer spring-lemon - 1.0.0.M9 + 1.0.0.RC1 diff --git a/spring-lemon-jpa/pom.xml b/spring-lemon-jpa/pom.xml index bbd9a95e..7d08ae06 100644 --- a/spring-lemon-jpa/pom.xml +++ b/spring-lemon-jpa/pom.xml @@ -13,7 +13,7 @@ com.naturalprogrammer spring-lemon - 1.0.0.M9 + 1.0.0.RC1 diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/LemonService.java b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/LemonService.java index 211e41c9..2949295c 100644 --- a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/LemonService.java +++ b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/LemonService.java @@ -464,7 +464,7 @@ public UserDto updateUser(U user, @Valid U updatedUser) { log.debug("Updating user: " + user); // checks - LemonUtils.ensureCorrectVersion(user, updatedUser); + LecjUtils.ensureCorrectVersion(user, updatedUser); // delegates to updateUserFields updateUserFields(user, updatedUser, LecwUtils.currentUser()); diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/util/LemonUtils.java b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/util/LemonUtils.java index 7065e9ff..7b4e824b 100644 --- a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/util/LemonUtils.java +++ b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/util/LemonUtils.java @@ -11,9 +11,7 @@ import com.naturalprogrammer.spring.lemon.commons.security.LemonPrincipal; import com.naturalprogrammer.spring.lemon.commons.security.LemonTokenService; import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; -import com.naturalprogrammer.spring.lemon.commonsjpa.LemonEntity; import com.naturalprogrammer.spring.lemon.domain.AbstractUser; -import com.naturalprogrammer.spring.lemon.exceptions.VersionException; import com.nimbusds.jwt.JWTClaimsSet; /** @@ -47,21 +45,6 @@ void login(U user) { SecurityContextHolder.getContext().setAuthentication(authentication); // put that in the security context principal.eraseCredentials(); } - - - /** - * Throws a VersionException if the versions of the - * given entities aren't same. - * - * @param original - * @param updated - */ - public static , ID extends Serializable> - void ensureCorrectVersion(LemonEntity original, LemonEntity updated) { - - if (original.getVersion() != updated.getVersion()) - throw new VersionException(original.getClass().getSimpleName(), original.getId().toString()); - } /** diff --git a/spring-lemon-reactive/pom.xml b/spring-lemon-reactive/pom.xml index 82040bfa..1c7c3119 100644 --- a/spring-lemon-reactive/pom.xml +++ b/spring-lemon-reactive/pom.xml @@ -13,7 +13,7 @@ com.naturalprogrammer spring-lemon - 1.0.0.M9 + 1.0.0.RC1 From c4ac9e7e010b7a9c23754f69a16eae43900ff60c Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Mon, 19 Nov 2018 22:03:01 +0530 Subject: [PATCH 081/116] Onto Spring Boot 2.1.0 update --- lemon-demo-jpa/src/main/resources/config/application.yml | 3 +++ .../naturalprogrammer/spring/lemondemo/UpdateUserMvcTests.java | 2 +- lemon-demo-reactive/src/main/resources/config/application.yml | 3 +++ .../naturalprogrammer/spring/lemondemo/UpdateUserTests.java | 2 +- pom.xml | 2 +- .../naturalprogrammer/spring/lemon/commonsjpa/LemonEntity.java | 2 +- .../spring/lemon/commonsmongo/AbstractDocument.java | 2 +- 7 files changed, 11 insertions(+), 5 deletions(-) diff --git a/lemon-demo-jpa/src/main/resources/config/application.yml b/lemon-demo-jpa/src/main/resources/config/application.yml index b273181b..880491fd 100644 --- a/lemon-demo-jpa/src/main/resources/config/application.yml +++ b/lemon-demo-jpa/src/main/resources/config/application.yml @@ -21,6 +21,9 @@ spring: # when source code changes restart.enabled: false livereload.enabled: false + + # https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-2.1-Release-Notes#bean-overriding + main.allow-bean-definition-overriding: true server.servlet.session.persistent: false diff --git a/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/UpdateUserMvcTests.java b/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/UpdateUserMvcTests.java index a94c2c2e..cbb53a49 100644 --- a/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/UpdateUserMvcTests.java +++ b/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/UpdateUserMvcTests.java @@ -78,7 +78,7 @@ public void testUpdateSelf() throws Exception { Assert.assertEquals(UNVERIFIED_USER_EMAIL, user.getEmail()); Assert.assertEquals(1, user.getRoles().size()); Assert.assertTrue(user.getRoles().contains(UserUtils.Role.UNVERIFIED)); - Assert.assertEquals(2L, user.getVersion()); + Assert.assertEquals(2L, user.getVersion().longValue()); // Version mismatch mvc.perform(patch("/api/core/users/{id}", UNVERIFIED_USER_ID) diff --git a/lemon-demo-reactive/src/main/resources/config/application.yml b/lemon-demo-reactive/src/main/resources/config/application.yml index d20bb70f..0737450c 100644 --- a/lemon-demo-reactive/src/main/resources/config/application.yml +++ b/lemon-demo-reactive/src/main/resources/config/application.yml @@ -13,6 +13,9 @@ spring: deserialization: accept-single-value-as-array: true + # https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-2.1-Release-Notes#bean-overriding + main.allow-bean-definition-overriding: true + # Spring Lemon related properties lemon: diff --git a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/UpdateUserTests.java b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/UpdateUserTests.java index e3826da7..faff1ecd 100644 --- a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/UpdateUserTests.java +++ b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/UpdateUserTests.java @@ -73,7 +73,7 @@ public void testUpdateSelf() throws Exception { assertEquals(UNVERIFIED_USER_EMAIL, user.getEmail()); assertEquals(1, user.getRoles().size()); assertTrue(user.getRoles().contains(UserUtils.Role.UNVERIFIED)); - assertEquals(1L, user.getVersion()); + assertEquals(1L, user.getVersion().longValue()); // Version mismatch updateUser(UNVERIFIED_USER_ID, UNVERIFIED_USER_ID, userPatch) diff --git a/pom.xml b/pom.xml index 3b8efa5d..2f73027e 100644 --- a/pom.xml +++ b/pom.xml @@ -15,7 +15,7 @@ org.springframework.boot spring-boot-starter-parent - 2.0.3.RELEASE + 2.1.0.RELEASE diff --git a/spring-lemon-commons-jpa/src/main/java/com/naturalprogrammer/spring/lemon/commonsjpa/LemonEntity.java b/spring-lemon-commons-jpa/src/main/java/com/naturalprogrammer/spring/lemon/commonsjpa/LemonEntity.java index 71fd9443..50ac1785 100644 --- a/spring-lemon-commons-jpa/src/main/java/com/naturalprogrammer/spring/lemon/commonsjpa/LemonEntity.java +++ b/spring-lemon-commons-jpa/src/main/java/com/naturalprogrammer/spring/lemon/commonsjpa/LemonEntity.java @@ -48,7 +48,7 @@ public class LemonEntity extends AbstractPersistable implements Permi private Date lastModifiedDate; @Version - private long version; + private Long version; /** * Whether the given user has the given permission for From 751e7d1911bbb0e0173b18eaa2bd3de4df19ecb3 Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Sun, 2 Dec 2018 13:31:56 +0530 Subject: [PATCH 082/116] Improved replacing RestOperations in LemonOAuth2UserService --- .../security/LemonOAuth2UserService.java | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonOAuth2UserService.java b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonOAuth2UserService.java index 4ec99dc4..068cfea9 100644 --- a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonOAuth2UserService.java +++ b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonOAuth2UserService.java @@ -1,16 +1,26 @@ package com.naturalprogrammer.spring.lemon.security; import java.io.Serializable; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; import java.util.Map; import org.apache.commons.lang3.exception.ExceptionUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.springframework.http.MediaType; +import org.springframework.http.converter.HttpMessageConverter; +import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.security.oauth2.client.http.OAuth2ErrorResponseErrorHandler; import org.springframework.security.oauth2.client.userinfo.DefaultOAuth2UserService; import org.springframework.security.oauth2.client.userinfo.OAuth2UserRequest; import org.springframework.security.oauth2.core.OAuth2AuthenticationException; import org.springframework.security.oauth2.core.user.OAuth2User; +import org.springframework.util.MimeType; +import org.springframework.web.client.RestTemplate; import com.naturalprogrammer.spring.lemon.LemonService; import com.naturalprogrammer.spring.lemon.commons.security.LemonPrincipal; @@ -39,9 +49,33 @@ public LemonOAuth2UserService( this.lemonService = lemonService; this.passwordEncoder = passwordEncoder; + replaceRestOperarions(); log.info("Created"); } + protected void replaceRestOperarions() { + + RestTemplate restTemplate = new RestTemplate(); + restTemplate.setErrorHandler(new OAuth2ErrorResponseErrorHandler()); + restTemplate.setMessageConverters(makeMessageConverters()); + setRestOperations(restTemplate); + + log.info("Rest Operations replaced"); + } + + protected List> makeMessageConverters() { + + log.info("Making message converters"); + + MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter(); + + List mediaTypes = new ArrayList<>(converter.getSupportedMediaTypes()); + mediaTypes.add(MediaType.asMediaType(new MimeType("text", "javascript", StandardCharsets.UTF_8))); // Facebook returns text/javascript + + converter.setSupportedMediaTypes(mediaTypes); + return Collections.singletonList(converter); + } + @Override public OAuth2User loadUser(OAuth2UserRequest userRequest) throws OAuth2AuthenticationException { From 09399662670d337abf26a4d1ecc92b0fdd4ce872 Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Sun, 2 Dec 2018 17:30:27 +0530 Subject: [PATCH 083/116] Updated CORS configurations --- ...LemonCommonsReactiveAutoConfiguration.java | 11 ++--- .../LemonCommonsReactiveSecurityConfig.java | 2 + .../LemonCorsConfigurationSource.java | 44 ++++++++++++++++++ .../security/LemonReactiveCorsConfig.java | 37 --------------- .../LemonCommonsWebAutoConfiguration.java | 11 ++--- .../commonsweb/security/LemonCorsConfig.java | 37 --------------- .../LemonCorsConfigurationSource.java | 45 +++++++++++++++++++ 7 files changed, 103 insertions(+), 84 deletions(-) create mode 100644 spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/security/LemonCorsConfigurationSource.java delete mode 100644 spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/security/LemonReactiveCorsConfig.java delete mode 100644 spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/security/LemonCorsConfig.java create mode 100644 spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/security/LemonCorsConfigurationSource.java diff --git a/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/LemonCommonsReactiveAutoConfiguration.java b/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/LemonCommonsReactiveAutoConfiguration.java index 462f6793..d3e2b769 100644 --- a/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/LemonCommonsReactiveAutoConfiguration.java +++ b/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/LemonCommonsReactiveAutoConfiguration.java @@ -21,6 +21,7 @@ import org.springframework.security.config.annotation.method.configuration.EnableReactiveMethodSecurity; import org.springframework.security.config.web.server.ServerHttpSecurity; import org.springframework.security.web.server.SecurityWebFilterChain; +import org.springframework.web.cors.reactive.CorsConfigurationSource; import com.fasterxml.jackson.databind.module.SimpleModule; import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; @@ -30,8 +31,8 @@ import com.naturalprogrammer.spring.lemon.commonsreactive.exceptions.LemonReactiveErrorAttributes; import com.naturalprogrammer.spring.lemon.commonsreactive.exceptions.handlers.VersionExceptionHandler; import com.naturalprogrammer.spring.lemon.commonsreactive.security.LemonCommonsReactiveSecurityConfig; +import com.naturalprogrammer.spring.lemon.commonsreactive.security.LemonCorsConfigurationSource; import com.naturalprogrammer.spring.lemon.commonsreactive.security.LemonReactiveAuditorAware; -import com.naturalprogrammer.spring.lemon.commonsreactive.security.LemonReactiveCorsConfig; import com.naturalprogrammer.spring.lemon.commonsreactive.util.LecrUtils; import com.naturalprogrammer.spring.lemon.exceptions.ErrorResponseComposer; import com.naturalprogrammer.spring.lemon.exceptions.util.LexUtils; @@ -96,11 +97,11 @@ public SecurityWebFilterChain springSecurityFilterChain( */ @Bean @ConditionalOnProperty(name="lemon.cors.allowed-origins") - @ConditionalOnMissingBean(LemonReactiveCorsConfig.class) - public LemonReactiveCorsConfig lemonCorsConfig(LemonProperties properties) { + @ConditionalOnMissingBean(CorsConfigurationSource.class) + public LemonCorsConfigurationSource corsConfigurationSource(LemonProperties properties) { - log.info("Configuring LemonCorsConfig"); - return new LemonReactiveCorsConfig(properties); + log.info("Configuring LemonCorsConfigurationSource"); + return new LemonCorsConfigurationSource(properties); } diff --git a/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/security/LemonCommonsReactiveSecurityConfig.java b/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/security/LemonCommonsReactiveSecurityConfig.java index af24a3a6..2c97c621 100644 --- a/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/security/LemonCommonsReactiveSecurityConfig.java +++ b/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/security/LemonCommonsReactiveSecurityConfig.java @@ -48,6 +48,8 @@ public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) .exceptionHandling() .accessDeniedHandler(accessDeniedHandler()) .authenticationEntryPoint(authenticationEntryPoint()) + .and() + .cors() .and() .csrf().disable() .addFilterAt(tokenAuthenticationFilter(), SecurityWebFiltersOrder.AUTHENTICATION) diff --git a/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/security/LemonCorsConfigurationSource.java b/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/security/LemonCorsConfigurationSource.java new file mode 100644 index 00000000..3648e8ec --- /dev/null +++ b/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/security/LemonCorsConfigurationSource.java @@ -0,0 +1,44 @@ +package com.naturalprogrammer.spring.lemon.commonsreactive.security; + +import java.util.Arrays; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.springframework.web.cors.CorsConfiguration; +import org.springframework.web.cors.reactive.CorsConfigurationSource; +import org.springframework.web.server.ServerWebExchange; + +import com.naturalprogrammer.spring.lemon.commons.LemonProperties; +import com.naturalprogrammer.spring.lemon.commons.LemonProperties.Cors; + +/** + * CORS Configuration + */ +public class LemonCorsConfigurationSource implements CorsConfigurationSource { + + private static final Log log = LogFactory.getLog(LemonCorsConfigurationSource.class); + + private Cors cors; + + public LemonCorsConfigurationSource(LemonProperties properties) { + + this.cors = properties.getCors(); + log.info("Created"); + } + + @Override + public CorsConfiguration getCorsConfiguration(ServerWebExchange exchange) { + + CorsConfiguration config = new CorsConfiguration(); + + config.setAllowCredentials(true); + config.setAllowedHeaders(Arrays.asList(cors.getAllowedHeaders())); + config.setAllowedMethods(Arrays.asList(cors.getAllowedMethods())); + config.setAllowedOrigins(Arrays.asList(cors.getAllowedOrigins())); + config.setExposedHeaders(Arrays.asList(cors.getExposedHeaders())); + config.setMaxAge(cors.getMaxAge()); + + return config; + } + +} diff --git a/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/security/LemonReactiveCorsConfig.java b/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/security/LemonReactiveCorsConfig.java deleted file mode 100644 index bc886f98..00000000 --- a/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/security/LemonReactiveCorsConfig.java +++ /dev/null @@ -1,37 +0,0 @@ -package com.naturalprogrammer.spring.lemon.commonsreactive.security; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.springframework.web.reactive.config.CorsRegistry; -import org.springframework.web.reactive.config.WebFluxConfigurer; - -import com.naturalprogrammer.spring.lemon.commons.LemonProperties; -import com.naturalprogrammer.spring.lemon.commons.LemonProperties.Cors; - -/** - * CORS Configuration - */ -public class LemonReactiveCorsConfig implements WebFluxConfigurer { - - private static final Log log = LogFactory.getLog(LemonReactiveCorsConfig.class); - - private Cors cors; - - public LemonReactiveCorsConfig(LemonProperties properties) { - - this.cors = properties.getCors(); - log.info("Created"); - } - - @Override - public void addCorsMappings(CorsRegistry registry) { - - registry.addMapping("/**") - .allowedOrigins(cors.getAllowedOrigins()) - .allowedMethods(cors.getAllowedMethods()) - .allowedHeaders(cors.getAllowedHeaders()) - .exposedHeaders(cors.getExposedHeaders()) - .allowCredentials(true) - .maxAge(cors.getMaxAge()); - } -} diff --git a/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/LemonCommonsWebAutoConfiguration.java b/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/LemonCommonsWebAutoConfiguration.java index c0fec38a..52471351 100644 --- a/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/LemonCommonsWebAutoConfiguration.java +++ b/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/LemonCommonsWebAutoConfiguration.java @@ -23,6 +23,7 @@ import org.springframework.data.web.config.EnableSpringDataWebSupport; import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; +import org.springframework.web.cors.CorsConfigurationSource; import com.fasterxml.jackson.databind.ObjectMapper; import com.naturalprogrammer.spring.lemon.commons.LemonCommonsAutoConfiguration; @@ -30,7 +31,7 @@ import com.naturalprogrammer.spring.lemon.commonsweb.exceptions.DefaultExceptionHandlerControllerAdvice; import com.naturalprogrammer.spring.lemon.commonsweb.exceptions.LemonErrorAttributes; import com.naturalprogrammer.spring.lemon.commonsweb.exceptions.LemonErrorController; -import com.naturalprogrammer.spring.lemon.commonsweb.security.LemonCorsConfig; +import com.naturalprogrammer.spring.lemon.commonsweb.security.LemonCorsConfigurationSource; import com.naturalprogrammer.spring.lemon.commonsweb.security.LemonWebAuditorAware; import com.naturalprogrammer.spring.lemon.commonsweb.security.LemonWebSecurityConfig; import com.naturalprogrammer.spring.lemon.commonsweb.util.LecwUtils; @@ -122,11 +123,11 @@ public ErrorController errorController(ErrorAttributes errorAttributes, */ @Bean @ConditionalOnProperty(name="lemon.cors.allowed-origins") - @ConditionalOnMissingBean(LemonCorsConfig.class) - public LemonCorsConfig lemonCorsConfig(LemonProperties properties) { + @ConditionalOnMissingBean(CorsConfigurationSource.class) + public LemonCorsConfigurationSource corsConfigurationSource(LemonProperties properties) { - log.info("Configuring LemonCorsConfig"); - return new LemonCorsConfig(properties); + log.info("Configuring LemonCorsConfigurationSource"); + return new LemonCorsConfigurationSource(properties); } /** diff --git a/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/security/LemonCorsConfig.java b/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/security/LemonCorsConfig.java deleted file mode 100644 index 4eb0cce2..00000000 --- a/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/security/LemonCorsConfig.java +++ /dev/null @@ -1,37 +0,0 @@ -package com.naturalprogrammer.spring.lemon.commonsweb.security; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.springframework.web.servlet.config.annotation.CorsRegistry; -import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; - -import com.naturalprogrammer.spring.lemon.commons.LemonProperties; -import com.naturalprogrammer.spring.lemon.commons.LemonProperties.Cors; - -/** - * CORS Configuration - */ -public class LemonCorsConfig implements WebMvcConfigurer { - - private static final Log log = LogFactory.getLog(LemonCorsConfig.class); - - private Cors cors; - - public LemonCorsConfig(LemonProperties properties) { - - this.cors = properties.getCors(); - log.info("Created"); - } - - @Override - public void addCorsMappings(CorsRegistry registry) { - - registry.addMapping("/**") - .allowedOrigins(cors.getAllowedOrigins()) - .allowedMethods(cors.getAllowedMethods()) - .allowedHeaders(cors.getAllowedHeaders()) - .exposedHeaders(cors.getExposedHeaders()) - .allowCredentials(true) - .maxAge(cors.getMaxAge()); - } -} diff --git a/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/security/LemonCorsConfigurationSource.java b/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/security/LemonCorsConfigurationSource.java new file mode 100644 index 00000000..3ea37cab --- /dev/null +++ b/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/security/LemonCorsConfigurationSource.java @@ -0,0 +1,45 @@ +package com.naturalprogrammer.spring.lemon.commonsweb.security; + +import java.util.Arrays; + +import javax.servlet.http.HttpServletRequest; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.springframework.web.cors.CorsConfiguration; +import org.springframework.web.cors.CorsConfigurationSource; + +import com.naturalprogrammer.spring.lemon.commons.LemonProperties; +import com.naturalprogrammer.spring.lemon.commons.LemonProperties.Cors; + +/** + * CORS Configuration + */ +public class LemonCorsConfigurationSource implements CorsConfigurationSource { + + private static final Log log = LogFactory.getLog(LemonCorsConfigurationSource.class); + + private Cors cors; + + public LemonCorsConfigurationSource(LemonProperties properties) { + + this.cors = properties.getCors(); + log.info("Created"); + } + + @Override + public CorsConfiguration getCorsConfiguration(HttpServletRequest request) { + + CorsConfiguration config = new CorsConfiguration(); + + config.setAllowCredentials(true); + config.setAllowedHeaders(Arrays.asList(cors.getAllowedHeaders())); + config.setAllowedMethods(Arrays.asList(cors.getAllowedMethods())); + config.setAllowedOrigins(Arrays.asList(cors.getAllowedOrigins())); + config.setExposedHeaders(Arrays.asList(cors.getExposedHeaders())); + config.setMaxAge(cors.getMaxAge()); + + return config; + } + +} From c67ffc5bf3a7316db8439c245bb86d56fb0ca00b Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Sun, 2 Dec 2018 17:54:40 +0530 Subject: [PATCH 084/116] Updated HttpCookieOAuth2AuthorizationRequestRepository to use the new removeAuthorizationRequest(request, response) --- ...tpCookieOAuth2AuthorizationRequestRepository.java | 12 ++++++++++-- .../security/OAuth2AuthenticationFailureHandler.java | 1 - .../security/OAuth2AuthenticationSuccessHandler.java | 1 - 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/HttpCookieOAuth2AuthorizationRequestRepository.java b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/HttpCookieOAuth2AuthorizationRequestRepository.java index c3f7cb78..f602e2b3 100644 --- a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/HttpCookieOAuth2AuthorizationRequestRepository.java +++ b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/HttpCookieOAuth2AuthorizationRequestRepository.java @@ -75,9 +75,11 @@ public void saveAuthorizationRequest(OAuth2AuthorizationRequest authorizationReq } @Override - public OAuth2AuthorizationRequest removeAuthorizationRequest(HttpServletRequest request) { + public OAuth2AuthorizationRequest removeAuthorizationRequest(HttpServletRequest request, HttpServletResponse response) { - return loadAuthorizationRequest(request); + OAuth2AuthorizationRequest originalRequest = loadAuthorizationRequest(request); + deleteCookies(request, response); + return originalRequest; } /** @@ -103,4 +105,10 @@ private OAuth2AuthorizationRequest deserialize(Cookie cookie) { return LecUtils.deserialize(cookie.getValue()); } + + @Deprecated + @Override + public OAuth2AuthorizationRequest removeAuthorizationRequest(HttpServletRequest request) { + throw new UnsupportedOperationException("Spring Security shouldn't have called the deprecated removeAuthorizationRequest(request)"); + } } diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/OAuth2AuthenticationFailureHandler.java b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/OAuth2AuthenticationFailureHandler.java index 3b3ba99f..d4ad61e9 100644 --- a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/OAuth2AuthenticationFailureHandler.java +++ b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/OAuth2AuthenticationFailureHandler.java @@ -21,7 +21,6 @@ public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException { - HttpCookieOAuth2AuthorizationRequestRepository.deleteCookies(request, response); super.onAuthenticationFailure(request, response, exception); } } diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/OAuth2AuthenticationSuccessHandler.java b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/OAuth2AuthenticationSuccessHandler.java index bcd609c3..75d7a1d8 100644 --- a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/OAuth2AuthenticationSuccessHandler.java +++ b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/OAuth2AuthenticationSuccessHandler.java @@ -48,7 +48,6 @@ protected String determineTargetUrl(HttpServletRequest request, .map(Cookie::getValue) .orElse(properties.getOauth2AuthenticationSuccessUrl()); - HttpCookieOAuth2AuthorizationRequestRepository.deleteCookies(request, response); return targetUrl + shortLivedAuthToken; } } From e6ecdc20c525d5c4df8fe7b181ace6c9b4f70cc7 Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Sun, 2 Dec 2018 18:06:39 +0530 Subject: [PATCH 085/116] Replaced the use of deprecated method with setServerAuthenticationConverter --- .../security/LemonCommonsReactiveSecurityConfig.java | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/security/LemonCommonsReactiveSecurityConfig.java b/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/security/LemonCommonsReactiveSecurityConfig.java index 2c97c621..2a04a1ee 100644 --- a/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/security/LemonCommonsReactiveSecurityConfig.java +++ b/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/security/LemonCommonsReactiveSecurityConfig.java @@ -1,7 +1,5 @@ package com.naturalprogrammer.spring.lemon.commonsreactive.security; -import java.util.function.Function; - import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.http.HttpHeaders; @@ -10,14 +8,13 @@ import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.config.web.server.SecurityWebFiltersOrder; import org.springframework.security.config.web.server.ServerHttpSecurity; -import org.springframework.security.core.Authentication; import org.springframework.security.web.server.SecurityWebFilterChain; import org.springframework.security.web.server.ServerAuthenticationEntryPoint; import org.springframework.security.web.server.authentication.AuthenticationWebFilter; +import org.springframework.security.web.server.authentication.ServerAuthenticationConverter; import org.springframework.security.web.server.authentication.ServerAuthenticationFailureHandler; import org.springframework.security.web.server.authorization.ServerAccessDeniedHandler; import org.springframework.security.web.server.context.NoOpServerSecurityContextRepository; -import org.springframework.web.server.ServerWebExchange; import com.naturalprogrammer.spring.lemon.commons.security.BlueTokenService; import com.naturalprogrammer.spring.lemon.commons.security.LemonPrincipal; @@ -79,7 +76,7 @@ protected void formLogin(ServerHttpSecurity http) { protected AuthenticationWebFilter tokenAuthenticationFilter() { AuthenticationWebFilter filter = new AuthenticationWebFilter(tokenAuthenticationManager()); - filter.setAuthenticationConverter(tokenAuthenticationConverter()); + filter.setServerAuthenticationConverter(tokenAuthenticationConverter()); filter.setAuthenticationFailureHandler(authenticationFailureHandler()); return filter; @@ -117,7 +114,7 @@ protected Mono fetchUserDto(JWTClaimsSet claims) { LexUtils.getMessage("com.naturalprogrammer.spring.userClaimAbsent"))); } - protected Function> tokenAuthenticationConverter() { + protected ServerAuthenticationConverter tokenAuthenticationConverter() { return serverWebExchange -> { From ee017adc6c47446bcb9b721de43bdca5dd8363b0 Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Sun, 2 Dec 2018 21:42:00 +0530 Subject: [PATCH 086/116] Updated Boot 2.1.0 to 2.1.1 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 2f73027e..0970ae10 100644 --- a/pom.xml +++ b/pom.xml @@ -15,7 +15,7 @@ org.springframework.boot spring-boot-starter-parent - 2.1.0.RELEASE + 2.1.1.RELEASE From ca2e567e83fb822f30f5f7ca26bd61f4e222397e Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Tue, 4 Dec 2018 18:02:14 +0530 Subject: [PATCH 087/116] Started adding OAuth2Login to reactive project --- .../security/LemonCommonsReactiveSecurityConfig.java | 9 +++++++++ .../security/LemonReactiveSecurityConfig.java | 8 ++++++++ 2 files changed, 17 insertions(+) diff --git a/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/security/LemonCommonsReactiveSecurityConfig.java b/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/security/LemonCommonsReactiveSecurityConfig.java index 2a04a1ee..6d9cd7dd 100644 --- a/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/security/LemonCommonsReactiveSecurityConfig.java +++ b/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/security/LemonCommonsReactiveSecurityConfig.java @@ -39,6 +39,7 @@ public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) formLogin(http); // Configure form login authorizeExchange(http); // configure authorization + oauth2Login(http); // configure OAuth2 login return http .securityContextRepository(NoOpServerSecurityContextRepository.getInstance()) @@ -54,6 +55,14 @@ public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) .build(); } + /** + * Override this to configure oauth2 Login + */ + protected void oauth2Login(ServerHttpSecurity http) { + + // Bypass here. OAuth2 login is needed only in the auth service + } + /** * Override this to configure authorization */ diff --git a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/security/LemonReactiveSecurityConfig.java b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/security/LemonReactiveSecurityConfig.java index 09a1b589..3e2a2e7f 100644 --- a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/security/LemonReactiveSecurityConfig.java +++ b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/security/LemonReactiveSecurityConfig.java @@ -51,6 +51,14 @@ protected String loginPage() { return "/api/core/login"; } + /** + * Configure OAuth2 login + */ + @Override + protected void oauth2Login(ServerHttpSecurity http) { + + http.oauth2Login(); // TODO: Configure properly + } @Override protected Mono fetchUserDto(JWTClaimsSet claims) { From e71fa3ce4d761b490f10efbffa768fc78a77fa9d Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Sat, 15 Dec 2018 19:36:13 +0530 Subject: [PATCH 088/116] Getting prepared for 1.0.0.RC2 --- lemon-demo-jpa/pom.xml | 2 +- .../naturalprogrammer/spring/lemondemo/AbstractMvcTests.java | 2 +- lemon-demo-reactive/pom.xml | 2 +- pom.xml | 2 +- spring-lemon-commons-jpa/pom.xml | 2 +- spring-lemon-commons-mongo/pom.xml | 2 +- spring-lemon-commons-reactive/pom.xml | 2 +- spring-lemon-commons-web/pom.xml | 2 +- spring-lemon-commons/pom.xml | 2 +- spring-lemon-exceptions/pom.xml | 2 +- spring-lemon-jpa/pom.xml | 2 +- spring-lemon-reactive/pom.xml | 2 +- 12 files changed, 12 insertions(+), 12 deletions(-) diff --git a/lemon-demo-jpa/pom.xml b/lemon-demo-jpa/pom.xml index 6cbc7160..c9252810 100644 --- a/lemon-demo-jpa/pom.xml +++ b/lemon-demo-jpa/pom.xml @@ -14,7 +14,7 @@ com.naturalprogrammer spring-lemon - 1.0.0.RC1 + 1.0.0.RC2 diff --git a/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/AbstractMvcTests.java b/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/AbstractMvcTests.java index 5d8f9926..f7af9fdd 100644 --- a/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/AbstractMvcTests.java +++ b/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/AbstractMvcTests.java @@ -33,7 +33,7 @@ "logging.level.org.springframework=ERROR", "lemon.recaptcha.sitekey=" }) -@AutoConfigureMockMvc(secure=false) +@AutoConfigureMockMvc @AutoConfigureTestDatabase(connection = EmbeddedDatabaseConnection.HSQL) @Sql({"/test-data/initialize.sql", "/test-data/finalize.sql"}) public abstract class AbstractMvcTests { diff --git a/lemon-demo-reactive/pom.xml b/lemon-demo-reactive/pom.xml index 3394af7c..66dbc083 100644 --- a/lemon-demo-reactive/pom.xml +++ b/lemon-demo-reactive/pom.xml @@ -13,7 +13,7 @@ com.naturalprogrammer spring-lemon - 1.0.0.RC1 + 1.0.0.RC2 diff --git a/pom.xml b/pom.xml index 0970ae10..2fdbbe34 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.naturalprogrammer spring-lemon - 1.0.0.RC1 + 1.0.0.RC2 pom spring-lemon diff --git a/spring-lemon-commons-jpa/pom.xml b/spring-lemon-commons-jpa/pom.xml index fdcc7067..d8fe17cb 100644 --- a/spring-lemon-commons-jpa/pom.xml +++ b/spring-lemon-commons-jpa/pom.xml @@ -13,7 +13,7 @@ com.naturalprogrammer spring-lemon - 1.0.0.RC1 + 1.0.0.RC2 diff --git a/spring-lemon-commons-mongo/pom.xml b/spring-lemon-commons-mongo/pom.xml index 4935a65d..ce018a74 100644 --- a/spring-lemon-commons-mongo/pom.xml +++ b/spring-lemon-commons-mongo/pom.xml @@ -13,7 +13,7 @@ com.naturalprogrammer spring-lemon - 1.0.0.RC1 + 1.0.0.RC2 diff --git a/spring-lemon-commons-reactive/pom.xml b/spring-lemon-commons-reactive/pom.xml index 6b5e6d23..9b4532b1 100644 --- a/spring-lemon-commons-reactive/pom.xml +++ b/spring-lemon-commons-reactive/pom.xml @@ -13,7 +13,7 @@ com.naturalprogrammer spring-lemon - 1.0.0.RC1 + 1.0.0.RC2 diff --git a/spring-lemon-commons-web/pom.xml b/spring-lemon-commons-web/pom.xml index a3b13d72..0b993ce4 100644 --- a/spring-lemon-commons-web/pom.xml +++ b/spring-lemon-commons-web/pom.xml @@ -13,7 +13,7 @@ com.naturalprogrammer spring-lemon - 1.0.0.RC1 + 1.0.0.RC2 diff --git a/spring-lemon-commons/pom.xml b/spring-lemon-commons/pom.xml index c680e5e9..58f9d884 100644 --- a/spring-lemon-commons/pom.xml +++ b/spring-lemon-commons/pom.xml @@ -14,7 +14,7 @@ com.naturalprogrammer spring-lemon - 1.0.0.RC1 + 1.0.0.RC2 diff --git a/spring-lemon-exceptions/pom.xml b/spring-lemon-exceptions/pom.xml index 7a64c1e7..81a42b07 100644 --- a/spring-lemon-exceptions/pom.xml +++ b/spring-lemon-exceptions/pom.xml @@ -13,7 +13,7 @@ com.naturalprogrammer spring-lemon - 1.0.0.RC1 + 1.0.0.RC2 diff --git a/spring-lemon-jpa/pom.xml b/spring-lemon-jpa/pom.xml index 7d08ae06..1c3ed371 100644 --- a/spring-lemon-jpa/pom.xml +++ b/spring-lemon-jpa/pom.xml @@ -13,7 +13,7 @@ com.naturalprogrammer spring-lemon - 1.0.0.RC1 + 1.0.0.RC2 diff --git a/spring-lemon-reactive/pom.xml b/spring-lemon-reactive/pom.xml index 1c7c3119..01d1053c 100644 --- a/spring-lemon-reactive/pom.xml +++ b/spring-lemon-reactive/pom.xml @@ -13,7 +13,7 @@ com.naturalprogrammer spring-lemon - 1.0.0.RC1 + 1.0.0.RC2 From 4dbe78ae92cf5d722508b069262f3a0e93c2bafe Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Sun, 3 Feb 2019 22:56:40 +0530 Subject: [PATCH 089/116] Fixed lemon-redirect_uri issue (#29) --- pom.xml | 184 +++++++------- ...eOAuth2AuthorizationRequestRepository.java | 228 +++++++++--------- .../OAuth2AuthenticationFailureHandler.java | 57 +++-- .../OAuth2AuthenticationSuccessHandler.java | 110 +++++---- 4 files changed, 294 insertions(+), 285 deletions(-) diff --git a/pom.xml b/pom.xml index 2fdbbe34..e06faf06 100644 --- a/pom.xml +++ b/pom.xml @@ -1,92 +1,92 @@ - - - 4.0.0 - - com.naturalprogrammer - spring-lemon - 1.0.0.RC2 - pom - - spring-lemon - Helper library for Spring Boot Web Applications - - - org.springframework.boot - spring-boot-starter-parent - 2.1.1.RELEASE - - - - - spring-lemon-exceptions - spring-lemon-commons - spring-lemon-commons-web - spring-lemon-commons-reactive - spring-lemon-commons-jpa - spring-lemon-commons-mongo - spring-lemon-jpa - spring-lemon-reactive - lemon-demo-jpa - lemon-demo-reactive - - - - - - org.projectlombok - lombok - true - - - - org.springframework.boot - spring-boot-starter-test - test - - - - - - - - - org.apache.maven.plugins - maven-source-plugin - - - attach-sources - - jar - - - - - - - org.apache.maven.plugins - maven-javadoc-plugin - - false - - - - attach-javadocs - - jar - - - - - - - - - - UTF-8 - UTF-8 - 1.8 - - - + + + 4.0.0 + + com.naturalprogrammer + spring-lemon + 1.0.0.RC2 + pom + + spring-lemon + Helper library for Spring Boot Web Applications + + + org.springframework.boot + spring-boot-starter-parent + 2.1.2.RELEASE + + + + + spring-lemon-exceptions + spring-lemon-commons + spring-lemon-commons-web + spring-lemon-commons-reactive + spring-lemon-commons-jpa + spring-lemon-commons-mongo + spring-lemon-jpa + spring-lemon-reactive + lemon-demo-jpa + lemon-demo-reactive + + + + + + org.projectlombok + lombok + true + + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + + + + org.apache.maven.plugins + maven-source-plugin + + + attach-sources + + jar + + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + + false + + + + attach-javadocs + + jar + + + + + + + + + + UTF-8 + UTF-8 + 1.8 + + + diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/HttpCookieOAuth2AuthorizationRequestRepository.java b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/HttpCookieOAuth2AuthorizationRequestRepository.java index f602e2b3..54734448 100644 --- a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/HttpCookieOAuth2AuthorizationRequestRepository.java +++ b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/HttpCookieOAuth2AuthorizationRequestRepository.java @@ -1,114 +1,114 @@ -package com.naturalprogrammer.spring.lemon.security; - -import javax.servlet.http.Cookie; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.apache.commons.lang3.StringUtils; -import org.springframework.security.oauth2.client.web.AuthorizationRequestRepository; -import org.springframework.security.oauth2.core.endpoint.OAuth2AuthorizationRequest; -import org.springframework.util.Assert; - -import com.naturalprogrammer.spring.lemon.commons.LemonProperties; -import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; -import com.naturalprogrammer.spring.lemon.commonsweb.util.LecwUtils; - -/** - * Cookie based repository for storing Authorization requests - */ -public class HttpCookieOAuth2AuthorizationRequestRepository implements AuthorizationRequestRepository { - - private static final String AUTHORIZATION_REQUEST_COOKIE_NAME = "lemon_oauth2_authorization_request"; - public static final String LEMON_REDIRECT_URI_COOKIE_PARAM_NAME = "lemon_redirect_uri"; - - private int cookieExpirySecs; - - public HttpCookieOAuth2AuthorizationRequestRepository(LemonProperties properties) { - - cookieExpirySecs = properties.getJwt().getShortLivedMillis() / 1000; - } - - /** - * Load authorization request from cookie - */ - @Override - public OAuth2AuthorizationRequest loadAuthorizationRequest(HttpServletRequest request) { - - Assert.notNull(request, "request cannot be null"); - - return LecwUtils.fetchCookie(request, AUTHORIZATION_REQUEST_COOKIE_NAME) - .map(this::deserialize) - .orElse(null); - } - - /** - * Save authorization request in cookie - */ - @Override - public void saveAuthorizationRequest(OAuth2AuthorizationRequest authorizationRequest, HttpServletRequest request, - HttpServletResponse response) { - - Assert.notNull(request, "request cannot be null"); - Assert.notNull(response, "response cannot be null"); - - if (authorizationRequest == null) { - - deleteCookies(request, response); - return; - } - - Cookie cookie = new Cookie(AUTHORIZATION_REQUEST_COOKIE_NAME, LecUtils.serialize(authorizationRequest)); - cookie.setPath("/"); - cookie.setHttpOnly(true); - cookie.setMaxAge(cookieExpirySecs); - response.addCookie(cookie); - - String lemonRedirectUri = request.getParameter(LEMON_REDIRECT_URI_COOKIE_PARAM_NAME); - if (StringUtils.isNotBlank(lemonRedirectUri)) { - - cookie = new Cookie(LEMON_REDIRECT_URI_COOKIE_PARAM_NAME, lemonRedirectUri); - cookie.setPath("/"); - cookie.setHttpOnly(true); - cookie.setMaxAge(cookieExpirySecs); - response.addCookie(cookie); - } - } - - @Override - public OAuth2AuthorizationRequest removeAuthorizationRequest(HttpServletRequest request, HttpServletResponse response) { - - OAuth2AuthorizationRequest originalRequest = loadAuthorizationRequest(request); - deleteCookies(request, response); - return originalRequest; - } - - /** - * Utility for deleting related cookies - */ - public static void deleteCookies(HttpServletRequest request, HttpServletResponse response) { - - Cookie[] cookies = request.getCookies(); - - if (cookies != null && cookies.length > 0) - for (int i = 0; i < cookies.length; i++) - if (cookies[i].getName().equals(AUTHORIZATION_REQUEST_COOKIE_NAME) || - cookies[i].getName().equals(LEMON_REDIRECT_URI_COOKIE_PARAM_NAME)) { - - cookies[i].setValue(""); - cookies[i].setPath("/"); - cookies[i].setMaxAge(0); - response.addCookie(cookies[i]); - } - } - - private OAuth2AuthorizationRequest deserialize(Cookie cookie) { - - return LecUtils.deserialize(cookie.getValue()); - } - - @Deprecated - @Override - public OAuth2AuthorizationRequest removeAuthorizationRequest(HttpServletRequest request) { - throw new UnsupportedOperationException("Spring Security shouldn't have called the deprecated removeAuthorizationRequest(request)"); - } -} +package com.naturalprogrammer.spring.lemon.security; + +import javax.servlet.http.Cookie; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.commons.lang3.ArrayUtils; +import org.apache.commons.lang3.StringUtils; +import org.springframework.security.oauth2.client.web.AuthorizationRequestRepository; +import org.springframework.security.oauth2.core.endpoint.OAuth2AuthorizationRequest; +import org.springframework.util.Assert; + +import com.naturalprogrammer.spring.lemon.commons.LemonProperties; +import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; +import com.naturalprogrammer.spring.lemon.commonsweb.util.LecwUtils; + +/** + * Cookie based repository for storing Authorization requests + */ +public class HttpCookieOAuth2AuthorizationRequestRepository implements AuthorizationRequestRepository { + + public static final String AUTHORIZATION_REQUEST_COOKIE_NAME = "lemon_oauth2_authorization_request"; + public static final String LEMON_REDIRECT_URI_COOKIE_PARAM_NAME = "lemon_redirect_uri"; + + private int cookieExpirySecs; + + public HttpCookieOAuth2AuthorizationRequestRepository(LemonProperties properties) { + + cookieExpirySecs = properties.getJwt().getShortLivedMillis() / 1000; + } + + /** + * Load authorization request from cookie + */ + @Override + public OAuth2AuthorizationRequest loadAuthorizationRequest(HttpServletRequest request) { + + Assert.notNull(request, "request cannot be null"); + + return LecwUtils.fetchCookie(request, AUTHORIZATION_REQUEST_COOKIE_NAME) + .map(this::deserialize) + .orElse(null); + } + + /** + * Save authorization request in cookie + */ + @Override + public void saveAuthorizationRequest(OAuth2AuthorizationRequest authorizationRequest, HttpServletRequest request, + HttpServletResponse response) { + + Assert.notNull(request, "request cannot be null"); + Assert.notNull(response, "response cannot be null"); + + if (authorizationRequest == null) { + + deleteCookies(request, response, AUTHORIZATION_REQUEST_COOKIE_NAME, LEMON_REDIRECT_URI_COOKIE_PARAM_NAME); + return; + } + + Cookie cookie = new Cookie(AUTHORIZATION_REQUEST_COOKIE_NAME, LecUtils.serialize(authorizationRequest)); + cookie.setPath("/"); + cookie.setHttpOnly(true); + cookie.setMaxAge(cookieExpirySecs); + response.addCookie(cookie); + + String lemonRedirectUri = request.getParameter(LEMON_REDIRECT_URI_COOKIE_PARAM_NAME); + if (StringUtils.isNotBlank(lemonRedirectUri)) { + + cookie = new Cookie(LEMON_REDIRECT_URI_COOKIE_PARAM_NAME, lemonRedirectUri); + cookie.setPath("/"); + cookie.setHttpOnly(true); + cookie.setMaxAge(cookieExpirySecs); + response.addCookie(cookie); + } + } + + @Override + public OAuth2AuthorizationRequest removeAuthorizationRequest(HttpServletRequest request, HttpServletResponse response) { + + OAuth2AuthorizationRequest originalRequest = loadAuthorizationRequest(request); + deleteCookies(request, response, AUTHORIZATION_REQUEST_COOKIE_NAME); + return originalRequest; + } + + /** + * Utility for deleting related cookies + */ + public static void deleteCookies(HttpServletRequest request, HttpServletResponse response, String... cookiesToDelete) { + + Cookie[] cookies = request.getCookies(); + + if (cookies != null && cookies.length > 0) + for (int i = 0; i < cookies.length; i++) + if (ArrayUtils.contains(cookiesToDelete, cookies[i].getName())) { + + cookies[i].setValue(""); + cookies[i].setPath("/"); + cookies[i].setMaxAge(0); + response.addCookie(cookies[i]); + } + } + + private OAuth2AuthorizationRequest deserialize(Cookie cookie) { + + return LecUtils.deserialize(cookie.getValue()); + } + + @Deprecated + @Override + public OAuth2AuthorizationRequest removeAuthorizationRequest(HttpServletRequest request) { + throw new UnsupportedOperationException("Spring Security shouldn't have called the deprecated removeAuthorizationRequest(request)"); + } +} diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/OAuth2AuthenticationFailureHandler.java b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/OAuth2AuthenticationFailureHandler.java index d4ad61e9..c7b5667f 100644 --- a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/OAuth2AuthenticationFailureHandler.java +++ b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/OAuth2AuthenticationFailureHandler.java @@ -1,26 +1,31 @@ -package com.naturalprogrammer.spring.lemon.security; - -import java.io.IOException; - -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.springframework.security.core.AuthenticationException; -import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler; - -/** - * OAuth2 Authentication failure handler for removing oauth2 related cookies - * - * @author Sanjay Patel - */ -public class OAuth2AuthenticationFailureHandler - extends SimpleUrlAuthenticationFailureHandler { - - public void onAuthenticationFailure(HttpServletRequest request, - HttpServletResponse response, AuthenticationException exception) - throws IOException, ServletException { - - super.onAuthenticationFailure(request, response, exception); - } -} +package com.naturalprogrammer.spring.lemon.security; + +import java.io.IOException; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.springframework.security.core.AuthenticationException; +import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler; + +/** + * OAuth2 Authentication failure handler for removing oauth2 related cookies + * + * @author Sanjay Patel + */ +public class OAuth2AuthenticationFailureHandler + extends SimpleUrlAuthenticationFailureHandler { + + @Override + public void onAuthenticationFailure(HttpServletRequest request, + HttpServletResponse response, AuthenticationException exception) + throws IOException, ServletException { + + HttpCookieOAuth2AuthorizationRequestRepository.deleteCookies(request, response, + HttpCookieOAuth2AuthorizationRequestRepository.AUTHORIZATION_REQUEST_COOKIE_NAME, + HttpCookieOAuth2AuthorizationRequestRepository.LEMON_REDIRECT_URI_COOKIE_PARAM_NAME); + + super.onAuthenticationFailure(request, response, exception); + } +} diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/OAuth2AuthenticationSuccessHandler.java b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/OAuth2AuthenticationSuccessHandler.java index 75d7a1d8..57f36c84 100644 --- a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/OAuth2AuthenticationSuccessHandler.java +++ b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/OAuth2AuthenticationSuccessHandler.java @@ -1,53 +1,57 @@ -package com.naturalprogrammer.spring.lemon.security; - -import java.io.Serializable; - -import javax.servlet.http.Cookie; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler; - -import com.naturalprogrammer.spring.lemon.commons.LemonProperties; -import com.naturalprogrammer.spring.lemon.commons.security.BlueTokenService; -import com.naturalprogrammer.spring.lemon.commons.security.UserDto; -import com.naturalprogrammer.spring.lemon.commonsweb.util.LecwUtils; - -import lombok.AllArgsConstructor; - -/** - * Authentication success handler for redirecting the - * OAuth2 signed in user to a URL with a short lived auth token - * - * @author Sanjay Patel - */ -@AllArgsConstructor -public class OAuth2AuthenticationSuccessHandler - extends SimpleUrlAuthenticationSuccessHandler { - - private static final Log log = LogFactory.getLog(OAuth2AuthenticationSuccessHandler.class); - - private LemonProperties properties; - private BlueTokenService blueTokenService; - - @Override - protected String determineTargetUrl(HttpServletRequest request, - HttpServletResponse response) { - - UserDto currentUser = LecwUtils.currentUser(); - - String shortLivedAuthToken = blueTokenService.createToken( - BlueTokenService.AUTH_AUDIENCE, - currentUser.getUsername(), - (long) properties.getJwt().getShortLivedMillis()); - - String targetUrl = LecwUtils.fetchCookie(request, - HttpCookieOAuth2AuthorizationRequestRepository.LEMON_REDIRECT_URI_COOKIE_PARAM_NAME) - .map(Cookie::getValue) - .orElse(properties.getOauth2AuthenticationSuccessUrl()); - - return targetUrl + shortLivedAuthToken; - } -} +package com.naturalprogrammer.spring.lemon.security; + +import java.io.Serializable; + +import javax.servlet.http.Cookie; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler; + +import com.naturalprogrammer.spring.lemon.commons.LemonProperties; +import com.naturalprogrammer.spring.lemon.commons.security.BlueTokenService; +import com.naturalprogrammer.spring.lemon.commons.security.UserDto; +import com.naturalprogrammer.spring.lemon.commonsweb.util.LecwUtils; + +import lombok.AllArgsConstructor; + +/** + * Authentication success handler for redirecting the + * OAuth2 signed in user to a URL with a short lived auth token + * + * @author Sanjay Patel + */ +@AllArgsConstructor +public class OAuth2AuthenticationSuccessHandler + extends SimpleUrlAuthenticationSuccessHandler { + + private static final Log log = LogFactory.getLog(OAuth2AuthenticationSuccessHandler.class); + + private LemonProperties properties; + private BlueTokenService blueTokenService; + + @Override + protected String determineTargetUrl(HttpServletRequest request, + HttpServletResponse response) { + + UserDto currentUser = LecwUtils.currentUser(); + + String shortLivedAuthToken = blueTokenService.createToken( + BlueTokenService.AUTH_AUDIENCE, + currentUser.getUsername(), + (long) properties.getJwt().getShortLivedMillis()); + + String targetUrl = LecwUtils.fetchCookie(request, + HttpCookieOAuth2AuthorizationRequestRepository.LEMON_REDIRECT_URI_COOKIE_PARAM_NAME) + .map(Cookie::getValue) + .orElse(properties.getOauth2AuthenticationSuccessUrl()); + + HttpCookieOAuth2AuthorizationRequestRepository.deleteCookies(request, response, + HttpCookieOAuth2AuthorizationRequestRepository.AUTHORIZATION_REQUEST_COOKIE_NAME, + HttpCookieOAuth2AuthorizationRequestRepository.LEMON_REDIRECT_URI_COOKIE_PARAM_NAME); + + return targetUrl + shortLivedAuthToken; + } +} From 8726496a6f1b1f82e6f97d5aefe538288940373b Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Sun, 3 Feb 2019 23:11:47 +0530 Subject: [PATCH 090/116] Getting prepared for RC3 --- lemon-demo-jpa/pom.xml | 2 +- lemon-demo-reactive/pom.xml | 2 +- pom.xml | 2 +- spring-lemon-commons-jpa/pom.xml | 2 +- spring-lemon-commons-mongo/pom.xml | 2 +- spring-lemon-commons-reactive/pom.xml | 2 +- spring-lemon-commons-web/pom.xml | 2 +- spring-lemon-commons/pom.xml | 138 +++++++++++++------------- spring-lemon-exceptions/pom.xml | 78 +++++++-------- spring-lemon-jpa/pom.xml | 68 ++++++------- spring-lemon-reactive/pom.xml | 70 ++++++------- 11 files changed, 184 insertions(+), 184 deletions(-) diff --git a/lemon-demo-jpa/pom.xml b/lemon-demo-jpa/pom.xml index c9252810..83bf617e 100644 --- a/lemon-demo-jpa/pom.xml +++ b/lemon-demo-jpa/pom.xml @@ -14,7 +14,7 @@ com.naturalprogrammer spring-lemon - 1.0.0.RC2 + 1.0.0.RC3 diff --git a/lemon-demo-reactive/pom.xml b/lemon-demo-reactive/pom.xml index 66dbc083..9f146cb0 100644 --- a/lemon-demo-reactive/pom.xml +++ b/lemon-demo-reactive/pom.xml @@ -13,7 +13,7 @@ com.naturalprogrammer spring-lemon - 1.0.0.RC2 + 1.0.0.RC3 diff --git a/pom.xml b/pom.xml index e06faf06..0482f76a 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.naturalprogrammer spring-lemon - 1.0.0.RC2 + 1.0.0.RC3 pom spring-lemon diff --git a/spring-lemon-commons-jpa/pom.xml b/spring-lemon-commons-jpa/pom.xml index d8fe17cb..9f2a0e1b 100644 --- a/spring-lemon-commons-jpa/pom.xml +++ b/spring-lemon-commons-jpa/pom.xml @@ -13,7 +13,7 @@ com.naturalprogrammer spring-lemon - 1.0.0.RC2 + 1.0.0.RC3 diff --git a/spring-lemon-commons-mongo/pom.xml b/spring-lemon-commons-mongo/pom.xml index ce018a74..50cb20c6 100644 --- a/spring-lemon-commons-mongo/pom.xml +++ b/spring-lemon-commons-mongo/pom.xml @@ -13,7 +13,7 @@ com.naturalprogrammer spring-lemon - 1.0.0.RC2 + 1.0.0.RC3 diff --git a/spring-lemon-commons-reactive/pom.xml b/spring-lemon-commons-reactive/pom.xml index 9b4532b1..4ad16d2b 100644 --- a/spring-lemon-commons-reactive/pom.xml +++ b/spring-lemon-commons-reactive/pom.xml @@ -13,7 +13,7 @@ com.naturalprogrammer spring-lemon - 1.0.0.RC2 + 1.0.0.RC3 diff --git a/spring-lemon-commons-web/pom.xml b/spring-lemon-commons-web/pom.xml index 0b993ce4..1ec0c889 100644 --- a/spring-lemon-commons-web/pom.xml +++ b/spring-lemon-commons-web/pom.xml @@ -13,7 +13,7 @@ com.naturalprogrammer spring-lemon - 1.0.0.RC2 + 1.0.0.RC3 diff --git a/spring-lemon-commons/pom.xml b/spring-lemon-commons/pom.xml index 58f9d884..ba829f92 100644 --- a/spring-lemon-commons/pom.xml +++ b/spring-lemon-commons/pom.xml @@ -1,69 +1,69 @@ - - - 4.0.0 - - com.naturalprogrammer.spring-lemon - spring-lemon-commons - jar - - spring-lemon-commons - Helper library for Spring Boot Web Applications - - - com.naturalprogrammer - spring-lemon - 1.0.0.RC2 - - - - - - com.naturalprogrammer.spring-lemon - spring-lemon-exceptions - ${project.version} - - - - org.springframework.data - spring-data-commons - - - - org.springframework.boot - spring-boot-starter-mail - - - - org.springframework.boot - spring-boot-starter-security - - - - org.springframework.security - spring-security-oauth2-client - - - - org.springframework.security - spring-security-oauth2-jose - - - - com.github.fge - json-patch - RELEASE - - - - - org.springframework.boot - spring-boot-configuration-processor - true - - - - - + + + 4.0.0 + + com.naturalprogrammer.spring-lemon + spring-lemon-commons + jar + + spring-lemon-commons + Helper library for Spring Boot Web Applications + + + com.naturalprogrammer + spring-lemon + 1.0.0.RC3 + + + + + + com.naturalprogrammer.spring-lemon + spring-lemon-exceptions + ${project.version} + + + + org.springframework.data + spring-data-commons + + + + org.springframework.boot + spring-boot-starter-mail + + + + org.springframework.boot + spring-boot-starter-security + + + + org.springframework.security + spring-security-oauth2-client + + + + org.springframework.security + spring-security-oauth2-jose + + + + com.github.fge + json-patch + RELEASE + + + + + org.springframework.boot + spring-boot-configuration-processor + true + + + + + diff --git a/spring-lemon-exceptions/pom.xml b/spring-lemon-exceptions/pom.xml index 81a42b07..d394c6f8 100644 --- a/spring-lemon-exceptions/pom.xml +++ b/spring-lemon-exceptions/pom.xml @@ -1,39 +1,39 @@ - - - 4.0.0 - - com.naturalprogrammer.spring-lemon - spring-lemon-exceptions - jar - - spring-lemon-exceptions - Helper exception handling library for Spring Boot REST APIs - - - com.naturalprogrammer - spring-lemon - 1.0.0.RC2 - - - - - - org.springframework - spring-web - - - - org.springframework.boot - spring-boot-starter-validation - - - - org.apache.commons - commons-lang3 - RELEASE - - - - - + + + 4.0.0 + + com.naturalprogrammer.spring-lemon + spring-lemon-exceptions + jar + + spring-lemon-exceptions + Helper exception handling library for Spring Boot REST APIs + + + com.naturalprogrammer + spring-lemon + 1.0.0.RC3 + + + + + + org.springframework + spring-web + + + + org.springframework.boot + spring-boot-starter-validation + + + + org.apache.commons + commons-lang3 + RELEASE + + + + + diff --git a/spring-lemon-jpa/pom.xml b/spring-lemon-jpa/pom.xml index 1c3ed371..24f32553 100644 --- a/spring-lemon-jpa/pom.xml +++ b/spring-lemon-jpa/pom.xml @@ -1,34 +1,34 @@ - - - 4.0.0 - - com.naturalprogrammer.spring-lemon - spring-lemon-jpa - jar - - spring-lemon-jpa - Helper library for Spring Boot JPA Web Applications - - - com.naturalprogrammer - spring-lemon - 1.0.0.RC2 - - - - - - com.naturalprogrammer.spring-lemon - spring-lemon-commons-jpa - ${project.version} - - - - javax.xml.bind - jaxb-api - - - - - + + + 4.0.0 + + com.naturalprogrammer.spring-lemon + spring-lemon-jpa + jar + + spring-lemon-jpa + Helper library for Spring Boot JPA Web Applications + + + com.naturalprogrammer + spring-lemon + 1.0.0.RC3 + + + + + + com.naturalprogrammer.spring-lemon + spring-lemon-commons-jpa + ${project.version} + + + + javax.xml.bind + jaxb-api + + + + + diff --git a/spring-lemon-reactive/pom.xml b/spring-lemon-reactive/pom.xml index 01d1053c..24c6821a 100644 --- a/spring-lemon-reactive/pom.xml +++ b/spring-lemon-reactive/pom.xml @@ -1,35 +1,35 @@ - - - 4.0.0 - - com.naturalprogrammer.spring-lemon - spring-lemon-reactive - jar - - spring-lemon-reactive - Helper reactive library for Spring Boot REST APIs - - - com.naturalprogrammer - spring-lemon - 1.0.0.RC2 - - - - - - com.naturalprogrammer.spring-lemon - spring-lemon-commons-mongo - ${project.version} - - - - io.projectreactor - reactor-test - test - - - - - + + + 4.0.0 + + com.naturalprogrammer.spring-lemon + spring-lemon-reactive + jar + + spring-lemon-reactive + Helper reactive library for Spring Boot REST APIs + + + com.naturalprogrammer + spring-lemon + 1.0.0.RC3 + + + + + + com.naturalprogrammer.spring-lemon + spring-lemon-commons-mongo + ${project.version} + + + + io.projectreactor + reactor-test + test + + + + + From d31bdfc6fefbdf1e6636add569405c78f71964c3 Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Sun, 17 Mar 2019 18:33:56 +0530 Subject: [PATCH 091/116] Made login endpoint configurable --- .../spring/lemon/commons/LemonProperties.java | 6 + .../security/LemonJpaSecurityConfig.java | 249 +++++++++--------- 2 files changed, 131 insertions(+), 124 deletions(-) diff --git a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/LemonProperties.java b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/LemonProperties.java index c4d7d23c..b6f3340f 100644 --- a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/LemonProperties.java +++ b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/LemonProperties.java @@ -41,6 +41,12 @@ public LemonProperties() { */ private String oauth2AuthenticationSuccessUrl = "http://localhost:9000/social-login-success?token="; + /** + * URL of the login endpoint + * e.g. POST /api/core/login + */ + private String loginUrl = "/api/core/login"; + /** * Recaptcha related properties */ diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonJpaSecurityConfig.java b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonJpaSecurityConfig.java index a8087272..954e5b8e 100644 --- a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonJpaSecurityConfig.java +++ b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonJpaSecurityConfig.java @@ -1,124 +1,125 @@ -package com.naturalprogrammer.spring.lemon.security; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.security.config.annotation.web.builders.HttpSecurity; -import org.springframework.security.crypto.password.PasswordEncoder; -import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler; -import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; - -import com.naturalprogrammer.spring.lemon.commons.LemonProperties; -import com.naturalprogrammer.spring.lemon.commonsweb.security.LemonWebSecurityConfig; - -/** - * Security configuration class. Extend it in the - * application, and make a configuration class. Override - * protected methods, if you need any customization. - * - * @author Sanjay Patel - */ -public class LemonJpaSecurityConfig extends LemonWebSecurityConfig { - - private static final Log log = LogFactory.getLog(LemonJpaSecurityConfig.class); - - private LemonProperties properties; - private LemonUserDetailsService userDetailsService; - private LemonAuthenticationSuccessHandler authenticationSuccessHandler; - private LemonOidcUserService oidcUserService; - private LemonOAuth2UserService oauth2UserService; - private OAuth2AuthenticationSuccessHandler oauth2AuthenticationSuccessHandler; - private OAuth2AuthenticationFailureHandler oauth2AuthenticationFailureHandler; - private PasswordEncoder passwordEncoder; - - @Autowired - public void createLemonSecurityConfig(LemonProperties properties, LemonUserDetailsService userDetailsService, - LemonAuthenticationSuccessHandler authenticationSuccessHandler, - LemonOidcUserService oidcUserService, - LemonOAuth2UserService oauth2UserService, - OAuth2AuthenticationSuccessHandler oauth2AuthenticationSuccessHandler, - OAuth2AuthenticationFailureHandler oauth2AuthenticationFailureHandler, - PasswordEncoder passwordEncoder) { - - this.properties = properties; - this.userDetailsService = userDetailsService; - this.authenticationSuccessHandler = authenticationSuccessHandler; - this.oidcUserService = oidcUserService; - this.oauth2UserService = oauth2UserService; - this.oauth2AuthenticationSuccessHandler = oauth2AuthenticationSuccessHandler; - this.oauth2AuthenticationFailureHandler = oauth2AuthenticationFailureHandler; - this.passwordEncoder = passwordEncoder; - - log.info("Created"); - } - - /** - * Security configuration, calling protected methods - */ - @Override - protected void configure(HttpSecurity http) throws Exception { - - super.configure(http); - login(http); // authentication - exceptionHandling(http); // exception handling - oauth2Client(http); - } - - - /** - * Configuring authentication. - */ - protected void login(HttpSecurity http) throws Exception { - - http - .formLogin() // form login - .loginPage(loginPage()) - - /****************************************** - * Setting a successUrl would redirect the user there. Instead, - * let's send 200 and the userDto along with an Authorization token. - *****************************************/ - .successHandler(authenticationSuccessHandler) - - /******************************************* - * Setting the failureUrl will redirect the user to - * that url if login fails. Instead, we need to send - * 401. So, let's set failureHandler instead. - *******************************************/ - .failureHandler(new SimpleUrlAuthenticationFailureHandler()); - } - - - /** - * Override this to change login URL - * - * @return - */ - protected String loginPage() { - - return "/api/core/login"; - } - - - protected void oauth2Client(HttpSecurity http) throws Exception { - - http.oauth2Login() - .authorizationEndpoint() - .authorizationRequestRepository(new HttpCookieOAuth2AuthorizationRequestRepository(properties)).and() - .successHandler(oauth2AuthenticationSuccessHandler) - .failureHandler(oauth2AuthenticationFailureHandler) - .userInfoEndpoint() - .oidcUserService(oidcUserService) - .userService(oauth2UserService); - } - - - /** - * Configuring token authentication filter - */ - protected void tokenAuthentication(HttpSecurity http) throws Exception { - - http.addFilterBefore(new LemonJpaTokenAuthenticationFilter(blueTokenService, userDetailsService), - UsernamePasswordAuthenticationFilter.class); - } -} +package com.naturalprogrammer.spring.lemon.security; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler; +import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; + +import com.naturalprogrammer.spring.lemon.commons.LemonProperties; +import com.naturalprogrammer.spring.lemon.commonsweb.security.LemonWebSecurityConfig; + +/** + * Security configuration class. Extend it in the + * application, and make a configuration class. Override + * protected methods, if you need any customization. + * + * @author Sanjay Patel + */ +public class LemonJpaSecurityConfig extends LemonWebSecurityConfig { + + private static final Log log = LogFactory.getLog(LemonJpaSecurityConfig.class); + + private LemonProperties properties; + private LemonUserDetailsService userDetailsService; + private LemonAuthenticationSuccessHandler authenticationSuccessHandler; + private LemonOidcUserService oidcUserService; + private LemonOAuth2UserService oauth2UserService; + private OAuth2AuthenticationSuccessHandler oauth2AuthenticationSuccessHandler; + private OAuth2AuthenticationFailureHandler oauth2AuthenticationFailureHandler; + private PasswordEncoder passwordEncoder; + + @Autowired + public void createLemonSecurityConfig(LemonProperties properties, LemonUserDetailsService userDetailsService, + LemonAuthenticationSuccessHandler authenticationSuccessHandler, + LemonOidcUserService oidcUserService, + LemonOAuth2UserService oauth2UserService, + OAuth2AuthenticationSuccessHandler oauth2AuthenticationSuccessHandler, + OAuth2AuthenticationFailureHandler oauth2AuthenticationFailureHandler, + PasswordEncoder passwordEncoder) { + + this.properties = properties; + this.userDetailsService = userDetailsService; + this.authenticationSuccessHandler = authenticationSuccessHandler; + this.oidcUserService = oidcUserService; + this.oauth2UserService = oauth2UserService; + this.oauth2AuthenticationSuccessHandler = oauth2AuthenticationSuccessHandler; + this.oauth2AuthenticationFailureHandler = oauth2AuthenticationFailureHandler; + this.passwordEncoder = passwordEncoder; + + log.info("Created"); + } + + /** + * Security configuration, calling protected methods + */ + @Override + protected void configure(HttpSecurity http) throws Exception { + + super.configure(http); + login(http); // authentication + exceptionHandling(http); // exception handling + oauth2Client(http); + } + + + /** + * Configuring authentication. + */ + protected void login(HttpSecurity http) throws Exception { + + http + .formLogin() // form login + .loginPage(loginPage()) + + /****************************************** + * Setting a successUrl would redirect the user there. Instead, + * let's send 200 and the userDto along with an Authorization token. + *****************************************/ + .successHandler(authenticationSuccessHandler) + + /******************************************* + * Setting the failureUrl will redirect the user to + * that url if login fails. Instead, we need to send + * 401. So, let's set failureHandler instead. + *******************************************/ + .failureHandler(new SimpleUrlAuthenticationFailureHandler()); + } + + + /** + * Override this to change login URL + * + * @return + */ + protected String loginPage() { + + return properties.getLoginUrl(); + } + + + protected void oauth2Client(HttpSecurity http) throws Exception { + + http.oauth2Login() + .authorizationEndpoint() + .authorizationRequestRepository(new HttpCookieOAuth2AuthorizationRequestRepository(properties)).and() + .successHandler(oauth2AuthenticationSuccessHandler) + .failureHandler(oauth2AuthenticationFailureHandler) + .userInfoEndpoint() + .oidcUserService(oidcUserService) + .userService(oauth2UserService); + } + + + /** + * Configuring token authentication filter + */ + @Override + protected void tokenAuthentication(HttpSecurity http) throws Exception { + + http.addFilterBefore(new LemonJpaTokenAuthenticationFilter(blueTokenService, userDetailsService), + UsernamePasswordAuthenticationFilter.class); + } +} From d9637c29e5b7413b3fb49531e1bef2a954d13116 Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Sat, 29 Jun 2019 04:44:10 +0530 Subject: [PATCH 092/116] Updated Spring Boot to 2.1.6 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 0482f76a..83587c5a 100644 --- a/pom.xml +++ b/pom.xml @@ -15,7 +15,7 @@ org.springframework.boot spring-boot-starter-parent - 2.1.2.RELEASE + 2.1.6.RELEASE From bfd628f5501ec38f2e17f1269079d1cf3f88ca0f Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Sat, 29 Jun 2019 06:58:42 +0530 Subject: [PATCH 093/116] Tiny typo fixes etc. --- .../security/LemonJpaSecurityConfig.java | 6 +- .../security/LemonOAuth2UserService.java | 258 +++++++++--------- .../security/LemonReactiveSecurityConfig.java | 152 +++++------ 3 files changed, 206 insertions(+), 210 deletions(-) diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonJpaSecurityConfig.java b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonJpaSecurityConfig.java index 954e5b8e..ab00714a 100644 --- a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonJpaSecurityConfig.java +++ b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonJpaSecurityConfig.java @@ -4,7 +4,6 @@ import org.apache.commons.logging.LogFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.config.annotation.web.builders.HttpSecurity; -import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; @@ -29,7 +28,6 @@ public class LemonJpaSecurityConfig extends LemonWebSecurityConfig { private LemonOAuth2UserService oauth2UserService; private OAuth2AuthenticationSuccessHandler oauth2AuthenticationSuccessHandler; private OAuth2AuthenticationFailureHandler oauth2AuthenticationFailureHandler; - private PasswordEncoder passwordEncoder; @Autowired public void createLemonSecurityConfig(LemonProperties properties, LemonUserDetailsService userDetailsService, @@ -37,8 +35,7 @@ public void createLemonSecurityConfig(LemonProperties properties, LemonUserDetai LemonOidcUserService oidcUserService, LemonOAuth2UserService oauth2UserService, OAuth2AuthenticationSuccessHandler oauth2AuthenticationSuccessHandler, - OAuth2AuthenticationFailureHandler oauth2AuthenticationFailureHandler, - PasswordEncoder passwordEncoder) { + OAuth2AuthenticationFailureHandler oauth2AuthenticationFailureHandler) { this.properties = properties; this.userDetailsService = userDetailsService; @@ -47,7 +44,6 @@ public void createLemonSecurityConfig(LemonProperties properties, LemonUserDetai this.oauth2UserService = oauth2UserService; this.oauth2AuthenticationSuccessHandler = oauth2AuthenticationSuccessHandler; this.oauth2AuthenticationFailureHandler = oauth2AuthenticationFailureHandler; - this.passwordEncoder = passwordEncoder; log.info("Created"); } diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonOAuth2UserService.java b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonOAuth2UserService.java index 068cfea9..d588e64c 100644 --- a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonOAuth2UserService.java +++ b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonOAuth2UserService.java @@ -1,129 +1,129 @@ -package com.naturalprogrammer.spring.lemon.security; - -import java.io.Serializable; -import java.nio.charset.StandardCharsets; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Map; - -import org.apache.commons.lang3.exception.ExceptionUtils; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.springframework.http.MediaType; -import org.springframework.http.converter.HttpMessageConverter; -import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; -import org.springframework.security.crypto.password.PasswordEncoder; -import org.springframework.security.oauth2.client.http.OAuth2ErrorResponseErrorHandler; -import org.springframework.security.oauth2.client.userinfo.DefaultOAuth2UserService; -import org.springframework.security.oauth2.client.userinfo.OAuth2UserRequest; -import org.springframework.security.oauth2.core.OAuth2AuthenticationException; -import org.springframework.security.oauth2.core.user.OAuth2User; -import org.springframework.util.MimeType; -import org.springframework.web.client.RestTemplate; - -import com.naturalprogrammer.spring.lemon.LemonService; -import com.naturalprogrammer.spring.lemon.commons.security.LemonPrincipal; -import com.naturalprogrammer.spring.lemon.commons.security.UserDto; -import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; -import com.naturalprogrammer.spring.lemon.domain.AbstractUser; -import com.naturalprogrammer.spring.lemon.exceptions.util.LexUtils; - -/** - * Logs in or registers a user after OAuth2 SignIn/Up - */ -public class LemonOAuth2UserService, ID extends Serializable> extends DefaultOAuth2UserService { - - private static final Log log = LogFactory.getLog(LemonOAuth2UserService.class); - - private LemonUserDetailsService userDetailsService; - private LemonService lemonService; - private PasswordEncoder passwordEncoder; - - public LemonOAuth2UserService( - LemonUserDetailsService userDetailsService, - LemonService lemonService, - PasswordEncoder passwordEncoder) { - - this.userDetailsService = userDetailsService; - this.lemonService = lemonService; - this.passwordEncoder = passwordEncoder; - - replaceRestOperarions(); - log.info("Created"); - } - - protected void replaceRestOperarions() { - - RestTemplate restTemplate = new RestTemplate(); - restTemplate.setErrorHandler(new OAuth2ErrorResponseErrorHandler()); - restTemplate.setMessageConverters(makeMessageConverters()); - setRestOperations(restTemplate); - - log.info("Rest Operations replaced"); - } - - protected List> makeMessageConverters() { - - log.info("Making message converters"); - - MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter(); - - List mediaTypes = new ArrayList<>(converter.getSupportedMediaTypes()); - mediaTypes.add(MediaType.asMediaType(new MimeType("text", "javascript", StandardCharsets.UTF_8))); // Facebook returns text/javascript - - converter.setSupportedMediaTypes(mediaTypes); - return Collections.singletonList(converter); - } - - @Override - public OAuth2User loadUser(OAuth2UserRequest userRequest) throws OAuth2AuthenticationException { - - OAuth2User oath2User = super.loadUser(userRequest); - return buildPrincipal(oath2User, userRequest.getClientRegistration().getRegistrationId()); - } - - /** - * Builds the security principal from the given userReqest. - * Registers the user if not already reqistered - */ - public LemonPrincipal buildPrincipal(OAuth2User oath2User, String registrationId) { - - Map attributes = oath2User.getAttributes(); - String email = lemonService.getOAuth2Email(registrationId, attributes); - LexUtils.validate(email != null, "com.naturalprogrammer.spring.oauth2EmailNeeded", registrationId).go(); - - boolean emailVerified = lemonService.getOAuth2AccountVerified(registrationId, attributes); - LexUtils.validate(emailVerified, "com.naturalprogrammer.spring.oauth2EmailNotVerified", registrationId).go(); - - U user = userDetailsService.findUserByUsername(email).orElseGet(() -> { - - // register a new user - U newUser = lemonService.newUser(); - newUser.setEmail(email); - newUser.setPassword(passwordEncoder.encode(LecUtils.uid())); - - lemonService.fillAdditionalFields(registrationId, newUser, attributes); - lemonService.save(newUser); - - try { - - lemonService.mailForgotPasswordLink(newUser); - - } catch (Throwable e) { - - // In case of exception, just log the error and keep silent - log.error(ExceptionUtils.getStackTrace(e)); - } - - return newUser; - }); - - UserDto userDto = user.toUserDto(); - LemonPrincipal principal = new LemonPrincipal(userDto); - principal.setAttributes(attributes); - principal.setName(oath2User.getName()); - - return principal; - } -} +package com.naturalprogrammer.spring.lemon.security; + +import java.io.Serializable; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Map; + +import org.apache.commons.lang3.exception.ExceptionUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.springframework.http.MediaType; +import org.springframework.http.converter.HttpMessageConverter; +import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.security.oauth2.client.http.OAuth2ErrorResponseErrorHandler; +import org.springframework.security.oauth2.client.userinfo.DefaultOAuth2UserService; +import org.springframework.security.oauth2.client.userinfo.OAuth2UserRequest; +import org.springframework.security.oauth2.core.OAuth2AuthenticationException; +import org.springframework.security.oauth2.core.user.OAuth2User; +import org.springframework.util.MimeType; +import org.springframework.web.client.RestTemplate; + +import com.naturalprogrammer.spring.lemon.LemonService; +import com.naturalprogrammer.spring.lemon.commons.security.LemonPrincipal; +import com.naturalprogrammer.spring.lemon.commons.security.UserDto; +import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; +import com.naturalprogrammer.spring.lemon.domain.AbstractUser; +import com.naturalprogrammer.spring.lemon.exceptions.util.LexUtils; + +/** + * Logs in or registers a user after OAuth2 SignIn/Up + */ +public class LemonOAuth2UserService, ID extends Serializable> extends DefaultOAuth2UserService { + + private static final Log log = LogFactory.getLog(LemonOAuth2UserService.class); + + private LemonUserDetailsService userDetailsService; + private LemonService lemonService; + private PasswordEncoder passwordEncoder; + + public LemonOAuth2UserService( + LemonUserDetailsService userDetailsService, + LemonService lemonService, + PasswordEncoder passwordEncoder) { + + this.userDetailsService = userDetailsService; + this.lemonService = lemonService; + this.passwordEncoder = passwordEncoder; + + replaceRestOperarions(); + log.info("Created"); + } + + protected void replaceRestOperarions() { + + RestTemplate restTemplate = new RestTemplate(); + restTemplate.setErrorHandler(new OAuth2ErrorResponseErrorHandler()); + restTemplate.setMessageConverters(makeMessageConverters()); + setRestOperations(restTemplate); + + log.info("Rest Operations replaced"); + } + + protected List> makeMessageConverters() { + + log.info("Making message converters"); + + MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter(); + + List mediaTypes = new ArrayList<>(converter.getSupportedMediaTypes()); + mediaTypes.add(MediaType.asMediaType(new MimeType("text", "javascript", StandardCharsets.UTF_8))); // Facebook returns text/javascript + + converter.setSupportedMediaTypes(mediaTypes); + return Collections.singletonList(converter); + } + + @Override + public OAuth2User loadUser(OAuth2UserRequest userRequest) throws OAuth2AuthenticationException { + + OAuth2User oath2User = super.loadUser(userRequest); + return buildPrincipal(oath2User, userRequest.getClientRegistration().getRegistrationId()); + } + + /** + * Builds the security principal from the given userReqest. + * Registers the user if not already registered + */ + public LemonPrincipal buildPrincipal(OAuth2User oath2User, String registrationId) { + + Map attributes = oath2User.getAttributes(); + String email = lemonService.getOAuth2Email(registrationId, attributes); + LexUtils.validate(email != null, "com.naturalprogrammer.spring.oauth2EmailNeeded", registrationId).go(); + + boolean emailVerified = lemonService.getOAuth2AccountVerified(registrationId, attributes); + LexUtils.validate(emailVerified, "com.naturalprogrammer.spring.oauth2EmailNotVerified", registrationId).go(); + + U user = userDetailsService.findUserByUsername(email).orElseGet(() -> { + + // register a new user + U newUser = lemonService.newUser(); + newUser.setEmail(email); + newUser.setPassword(passwordEncoder.encode(LecUtils.uid())); + + lemonService.fillAdditionalFields(registrationId, newUser, attributes); + lemonService.save(newUser); + + try { + + lemonService.mailForgotPasswordLink(newUser); + + } catch (Throwable e) { + + // In case of exception, just log the error and keep silent + log.error(ExceptionUtils.getStackTrace(e)); + } + + return newUser; + }); + + UserDto userDto = user.toUserDto(); + LemonPrincipal principal = new LemonPrincipal(userDto); + principal.setAttributes(attributes); + principal.setName(oath2User.getName()); + + return principal; + } +} diff --git a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/security/LemonReactiveSecurityConfig.java b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/security/LemonReactiveSecurityConfig.java index 3e2a2e7f..211a19ee 100644 --- a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/security/LemonReactiveSecurityConfig.java +++ b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/security/LemonReactiveSecurityConfig.java @@ -1,76 +1,76 @@ -package com.naturalprogrammer.spring.lemonreactive.security; - -import java.io.Serializable; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.springframework.security.config.web.server.ServerHttpSecurity; -import org.springframework.security.core.userdetails.UsernameNotFoundException; -import org.springframework.security.web.server.authentication.WebFilterChainServerAuthenticationSuccessHandler; - -import com.naturalprogrammer.spring.lemon.commons.security.BlueTokenService; -import com.naturalprogrammer.spring.lemon.commons.security.UserDto; -import com.naturalprogrammer.spring.lemon.commonsreactive.security.LemonCommonsReactiveSecurityConfig; -import com.naturalprogrammer.spring.lemonreactive.domain.AbstractMongoUser; -import com.naturalprogrammer.spring.lemonreactive.util.LerUtils; -import com.nimbusds.jwt.JWTClaimsSet; - -import reactor.core.publisher.Mono; - -public class LemonReactiveSecurityConfig , ID extends Serializable> extends LemonCommonsReactiveSecurityConfig { - - private static final Log log = LogFactory.getLog(LemonReactiveSecurityConfig.class); - - protected LemonReactiveUserDetailsService userDetailsService; - - public LemonReactiveSecurityConfig(BlueTokenService blueTokenService, - LemonReactiveUserDetailsService userDetailsService) { - - super(blueTokenService); - this.userDetailsService = userDetailsService; - log.info("Created"); - } - - /** - * Configure form login - */ - @Override - protected void formLogin(ServerHttpSecurity http) { - - http.formLogin() - .loginPage(loginPage()) // Should be "/login" by default, but not providing that overwrites our AuthenticationFailureHandler, because this is called later - .authenticationFailureHandler(authenticationFailureHandler()) - .authenticationSuccessHandler(new WebFilterChainServerAuthenticationSuccessHandler()); - } - - /** - * Override this to change login URL - */ - protected String loginPage() { - - return "/api/core/login"; - } - - /** - * Configure OAuth2 login - */ - @Override - protected void oauth2Login(ServerHttpSecurity http) { - - http.oauth2Login(); // TODO: Configure properly - } - - @Override - protected Mono fetchUserDto(JWTClaimsSet claims) { - - String username = claims.getSubject(); - - return userDetailsService.findUserByUsername(username) - .switchIfEmpty(Mono.defer(() -> Mono.error(new UsernameNotFoundException(username)))) - .doOnNext(user -> { - log.debug("User found ..."); - LerUtils.ensureCredentialsUpToDate(claims, user); - }) - .map(AbstractMongoUser::toUserDto); - } -} +package com.naturalprogrammer.spring.lemonreactive.security; + +import java.io.Serializable; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.springframework.security.config.web.server.ServerHttpSecurity; +import org.springframework.security.core.userdetails.UsernameNotFoundException; +import org.springframework.security.web.server.authentication.WebFilterChainServerAuthenticationSuccessHandler; + +import com.naturalprogrammer.spring.lemon.commons.security.BlueTokenService; +import com.naturalprogrammer.spring.lemon.commons.security.UserDto; +import com.naturalprogrammer.spring.lemon.commonsreactive.security.LemonCommonsReactiveSecurityConfig; +import com.naturalprogrammer.spring.lemonreactive.domain.AbstractMongoUser; +import com.naturalprogrammer.spring.lemonreactive.util.LerUtils; +import com.nimbusds.jwt.JWTClaimsSet; + +import reactor.core.publisher.Mono; + +public class LemonReactiveSecurityConfig, ID extends Serializable> extends LemonCommonsReactiveSecurityConfig { + + private static final Log log = LogFactory.getLog(LemonReactiveSecurityConfig.class); + + protected LemonReactiveUserDetailsService userDetailsService; + + public LemonReactiveSecurityConfig(BlueTokenService blueTokenService, + LemonReactiveUserDetailsService userDetailsService) { + + super(blueTokenService); + this.userDetailsService = userDetailsService; + log.info("Created"); + } + + /** + * Configure form login + */ + @Override + protected void formLogin(ServerHttpSecurity http) { + + http.formLogin() + .loginPage(loginPage()) // Should be "/login" by default, but not providing that overwrites our AuthenticationFailureHandler, because this is called later + .authenticationFailureHandler(authenticationFailureHandler()) + .authenticationSuccessHandler(new WebFilterChainServerAuthenticationSuccessHandler()); + } + + /** + * Override this to change login URL + */ + protected String loginPage() { + + return "/api/core/login"; + } + + /** + * Configure OAuth2 login + */ + @Override + protected void oauth2Login(ServerHttpSecurity http) { + + http.oauth2Login(); // TODO: Configure properly + } + + @Override + protected Mono fetchUserDto(JWTClaimsSet claims) { + + String username = claims.getSubject(); + + return userDetailsService.findUserByUsername(username) + .switchIfEmpty(Mono.defer(() -> Mono.error(new UsernameNotFoundException(username)))) + .doOnNext(user -> { + log.debug("User found ..."); + LerUtils.ensureCredentialsUpToDate(claims, user); + }) + .map(AbstractMongoUser::toUserDto); + } +} From e4a3813743fb92a19a82c37544a6fc97c9b824a2 Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Thu, 19 Sep 2019 07:19:32 +0530 Subject: [PATCH 094/116] Towards Spring Boot 2.2, and reactive oauth --- lemon-demo-angularjs/package.json | 2 +- .../resources/ValidationMessages.properties | 21 ++++ .../src/main/resources/messages.properties | 22 ---- .../spring/lemondemo/SignupMvcTests.java | 12 +- .../resources/ValidationMessages.properties | 20 ++++ .../src/main/resources/messages.properties | 22 ---- .../spring/lemondemo/SignupTests.java | 21 ++++ pom.xml | 26 +++- .../LemonCommonsWebAutoConfiguration.java | 2 +- .../LemonCommonsAutoConfiguration.java | 5 +- .../commons/validation/CaptchaValidator.java | 5 +- .../LemonExceptionsAutoConfiguration.java | 14 --- .../LemonReactiveAutoConfiguration.java | 6 +- .../security/LemonReactiveSecurityConfig.java | 12 +- ...erverOAuth2AuthorizedClientRepository.java | 112 ++++++++++++++++++ .../spring/lemonreactive/util/LerUtils.java | 7 ++ 16 files changed, 237 insertions(+), 72 deletions(-) create mode 100644 lemon-demo-jpa/src/main/resources/ValidationMessages.properties create mode 100644 lemon-demo-reactive/src/main/resources/ValidationMessages.properties create mode 100644 spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/security/ReactiveCookieServerOAuth2AuthorizedClientRepository.java diff --git a/lemon-demo-angularjs/package.json b/lemon-demo-angularjs/package.json index 4f783b6f..6faefb36 100644 --- a/lemon-demo-angularjs/package.json +++ b/lemon-demo-angularjs/package.json @@ -2,7 +2,7 @@ "name": "angularsample", "version": "0.0.0", "dependencies": { - "natives": "^1.1.5", + "natives": "^1.1.6", "wiredep": "^2.2.2" }, "repository": {}, diff --git a/lemon-demo-jpa/src/main/resources/ValidationMessages.properties b/lemon-demo-jpa/src/main/resources/ValidationMessages.properties new file mode 100644 index 00000000..cc83a2f6 --- /dev/null +++ b/lemon-demo-jpa/src/main/resources/ValidationMessages.properties @@ -0,0 +1,21 @@ +# +## Spring Lemon Bean Validation messages +# + +com.naturalprogrammer.spring.blank.email: Email needed +com.naturalprogrammer.spring.invalid.email: Not a well formed email address +com.naturalprogrammer.spring.invalid.email.size: Email must be between {min} and {max} characters +com.naturalprogrammer.spring.duplicate.email: Email Id already used +com.naturalprogrammer.spring.wrong.captcha: Looks like you are a robot! Please try again. + +com.naturalprogrammer.spring.invalid.password.size: Password must be between {min} and {max} characters + +com.naturalprogrammer.spring.different.passwords: Passwords do not match +com.naturalprogrammer.spring.blank.password: Password needed + + +# +## My Bean Validation Messages +# + +blank.name: Name required diff --git a/lemon-demo-jpa/src/main/resources/messages.properties b/lemon-demo-jpa/src/main/resources/messages.properties index aeed1c06..538f11be 100644 --- a/lemon-demo-jpa/src/main/resources/messages.properties +++ b/lemon-demo-jpa/src/main/resources/messages.properties @@ -42,28 +42,6 @@ com.naturalprogrammer.spring.blank: Please provide {0} com.naturalprogrammer.spring.userClaimAbsent: User claim absent in the authorization token com.naturalprogrammer.spring.fullTokenNotAllowed: Full authorization tokens aren't allowed here -# -## Spring Lemon Bean Validation messages -# - -com.naturalprogrammer.spring.blank.email: Email needed -com.naturalprogrammer.spring.invalid.email: Not a well formed email address -com.naturalprogrammer.spring.invalid.email.size: Email must be between {min} and {max} characters -com.naturalprogrammer.spring.duplicate.email: Email Id already used -com.naturalprogrammer.spring.wrong.captcha: Looks like you are a robot! Please try again. - -com.naturalprogrammer.spring.invalid.password.size: Password must be between {min} and {max} characters - -com.naturalprogrammer.spring.different.passwords: Passwords do not match -com.naturalprogrammer.spring.blank.password: Password needed - # ## My Normal Messages -# - - # -## My Bean Validation Messages -# - -blank.name: Name required diff --git a/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/SignupMvcTests.java b/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/SignupMvcTests.java index 555df548..3deb00c7 100644 --- a/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/SignupMvcTests.java +++ b/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/SignupMvcTests.java @@ -33,7 +33,17 @@ public void testSignupWithInvalidData() throws Exception { .andExpect(status().is(422)) .andExpect(jsonPath("$.errors[*].field").value(hasSize(4))) .andExpect(jsonPath("$.errors[*].field").value(hasItems( - "user.email", "user.password", "user.name"))); + "user.email", "user.password", "user.name"))) + .andExpect(jsonPath("$.errors[*].code").value(hasItems( + "{com.naturalprogrammer.spring.invalid.email}", + "{blank.name}", + "{com.naturalprogrammer.spring.invalid.email.size}", + "{com.naturalprogrammer.spring.invalid.password.size}"))) + .andExpect(jsonPath("$.errors[*].message").value(hasItems( + "Not a well formed email address", + "Name required", + "Email must be between 4 and 250 characters", + "Password must be between 6 and 50 characters"))); verify(mailSender, never()).send(any()); } diff --git a/lemon-demo-reactive/src/main/resources/ValidationMessages.properties b/lemon-demo-reactive/src/main/resources/ValidationMessages.properties new file mode 100644 index 00000000..533b725f --- /dev/null +++ b/lemon-demo-reactive/src/main/resources/ValidationMessages.properties @@ -0,0 +1,20 @@ +# +## Spring Lemon Bean Validation messages +# + +com.naturalprogrammer.spring.blank.email: Email needed +com.naturalprogrammer.spring.invalid.email: Not a well formed email address +com.naturalprogrammer.spring.invalid.email.size: Email must be between {min} and {max} characters +com.naturalprogrammer.spring.duplicate.email: Email Id already used +com.naturalprogrammer.spring.wrong.captcha: Looks like you are a robot! Please try again. + +com.naturalprogrammer.spring.invalid.password.size: Password must be between {min} and {max} characters + +com.naturalprogrammer.spring.different.passwords: Passwords do not match +com.naturalprogrammer.spring.blank.password: Password needed + +# +## My Bean Validation Messages +# + +blank.name: Name required diff --git a/lemon-demo-reactive/src/main/resources/messages.properties b/lemon-demo-reactive/src/main/resources/messages.properties index aeed1c06..4be0d170 100644 --- a/lemon-demo-reactive/src/main/resources/messages.properties +++ b/lemon-demo-reactive/src/main/resources/messages.properties @@ -42,28 +42,6 @@ com.naturalprogrammer.spring.blank: Please provide {0} com.naturalprogrammer.spring.userClaimAbsent: User claim absent in the authorization token com.naturalprogrammer.spring.fullTokenNotAllowed: Full authorization tokens aren't allowed here -# -## Spring Lemon Bean Validation messages -# - -com.naturalprogrammer.spring.blank.email: Email needed -com.naturalprogrammer.spring.invalid.email: Not a well formed email address -com.naturalprogrammer.spring.invalid.email.size: Email must be between {min} and {max} characters -com.naturalprogrammer.spring.duplicate.email: Email Id already used -com.naturalprogrammer.spring.wrong.captcha: Looks like you are a robot! Please try again. - -com.naturalprogrammer.spring.invalid.password.size: Password must be between {min} and {max} characters - -com.naturalprogrammer.spring.different.passwords: Passwords do not match -com.naturalprogrammer.spring.blank.password: Password needed - # ## My Normal Messages # - - -# -## My Bean Validation Messages -# - -blank.name: Name required diff --git a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/SignupTests.java b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/SignupTests.java index 9b333801..1ea5f527 100644 --- a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/SignupTests.java +++ b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/SignupTests.java @@ -16,6 +16,10 @@ import static org.springframework.data.mongodb.core.query.Criteria.where; import static org.springframework.data.mongodb.core.query.Query.query; +import java.util.Arrays; +import java.util.Collection; +import java.util.stream.Collectors; + import org.junit.Test; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; @@ -24,6 +28,7 @@ import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; import com.naturalprogrammer.spring.lemondemo.domain.User; import com.naturalprogrammer.spring.lemondemo.dto.TestErrorResponse; +import com.naturalprogrammer.spring.lemondemo.dto.TestLemonFieldError; import com.naturalprogrammer.spring.lemondemo.dto.TestUser; import com.naturalprogrammer.spring.lemondemo.dto.TestUserDto; @@ -73,6 +78,22 @@ public void testSignupWithInvalidData() throws Exception { "userMono.email", "userMono.password", "userMono.name"); + + Collection errors = errorResponseResult.getResponseBody().getErrors(); + assertTrue(errors.stream() + .map(TestLemonFieldError::getCode).collect(Collectors.toSet()) + .containsAll(Arrays.asList( + "NotBlank", + "Size", + "Email"))); + + assertTrue(errors.stream() + .map(TestLemonFieldError::getMessage).collect(Collectors.toSet()) + .containsAll(Arrays.asList( + "Not a well formed email address", + "Name required", + "Email must be between 4 and 250 characters", + "Password must be between 6 and 50 characters"))); }); verify(mailSender, never()).send(any()); diff --git a/pom.xml b/pom.xml index 83587c5a..03425be5 100644 --- a/pom.xml +++ b/pom.xml @@ -15,7 +15,7 @@ org.springframework.boot spring-boot-starter-parent - 2.1.6.RELEASE + 2.2.0.BUILD-SNAPSHOT @@ -89,4 +89,28 @@ 1.8 + + + + + spring-snapshots + https://repo.spring.io/snapshot + true + + + spring-milestones + https://repo.spring.io/milestone + + + + + spring-snapshots + https://repo.spring.io/snapshot + + + spring-milestones + https://repo.spring.io/milestone + + + diff --git a/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/LemonCommonsWebAutoConfiguration.java b/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/LemonCommonsWebAutoConfiguration.java index 52471351..f5f45cb7 100644 --- a/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/LemonCommonsWebAutoConfiguration.java +++ b/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/LemonCommonsWebAutoConfiguration.java @@ -61,7 +61,7 @@ public LemonCommonsWebAutoConfiguration() { log.info("Created"); } - /** + /** * Prefixes JSON responses for JSON vulnerability. Disabled by default. * To enable, add this to your application properties: * lemon.enabled.json-prefix: true diff --git a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/LemonCommonsAutoConfiguration.java b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/LemonCommonsAutoConfiguration.java index 2ac33881..6416617b 100644 --- a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/LemonCommonsAutoConfiguration.java +++ b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/LemonCommonsAutoConfiguration.java @@ -5,7 +5,6 @@ import org.springframework.boot.autoconfigure.AutoConfigureBefore; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.boot.web.client.RestTemplateBuilder; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; @@ -142,9 +141,9 @@ public LecUtils lecUtils(ApplicationContext applicationContext, ObjectMapper obj */ @Bean @ConditionalOnMissingBean(CaptchaValidator.class) - public CaptchaValidator captchaValidator(LemonProperties properties, RestTemplateBuilder restTemplateBuilder) { + public CaptchaValidator captchaValidator(LemonProperties properties) { log.info("Configuring LemonUserDetailsService"); - return new CaptchaValidator(properties, restTemplateBuilder); + return new CaptchaValidator(properties); } } diff --git a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/validation/CaptchaValidator.java b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/validation/CaptchaValidator.java index fac328f9..00876edb 100644 --- a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/validation/CaptchaValidator.java +++ b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/validation/CaptchaValidator.java @@ -9,7 +9,6 @@ import org.apache.commons.lang3.exception.ExceptionUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import org.springframework.boot.web.client.RestTemplateBuilder; import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; import org.springframework.web.client.RestTemplate; @@ -61,10 +60,10 @@ public void setErrorCodes(Collection errorCodes) { private LemonProperties properties; private RestTemplate restTemplate; - public CaptchaValidator(LemonProperties properties, RestTemplateBuilder restTemplateBuilder) { + public CaptchaValidator(LemonProperties properties) { this.properties = properties; - this.restTemplate = restTemplateBuilder.build();; + this.restTemplate = new RestTemplate(); log.info("Created"); } diff --git a/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/LemonExceptionsAutoConfiguration.java b/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/LemonExceptionsAutoConfiguration.java index 30d3999f..cefff437 100644 --- a/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/LemonExceptionsAutoConfiguration.java +++ b/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/LemonExceptionsAutoConfiguration.java @@ -2,8 +2,6 @@ import java.util.List; -import javax.validation.Validator; - import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.boot.autoconfigure.AutoConfigureBefore; @@ -72,16 +70,4 @@ public LexUtils lexUtils(MessageSource messageSource, log.info("Configuring LexUtils"); return new LexUtils(messageSource, validator, exceptionIdMaker); } - - /** - * Merge ValidationMessages.properties into messages.properties - */ - @Bean - @ConditionalOnMissingBean(Validator.class) - public Validator validator(MessageSource messageSource) { - - LocalValidatorFactoryBean localValidatorFactoryBean = new LocalValidatorFactoryBean(); - localValidatorFactoryBean.setValidationMessageSource(messageSource); - return localValidatorFactoryBean; - } } diff --git a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveAutoConfiguration.java b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveAutoConfiguration.java index 8bd2dc7a..102f994b 100644 --- a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveAutoConfiguration.java +++ b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveAutoConfiguration.java @@ -11,6 +11,7 @@ import org.springframework.context.annotation.Configuration; import org.springframework.security.core.userdetails.UserDetailsService; +import com.naturalprogrammer.spring.lemon.commons.LemonProperties; import com.naturalprogrammer.spring.lemon.commons.domain.IdConverter; import com.naturalprogrammer.spring.lemon.commons.security.BlueTokenService; import com.naturalprogrammer.spring.lemon.commonsmongo.LemonCommonsMongoAutoConfiguration; @@ -45,11 +46,12 @@ IdConverter idConverter(LemonReactiveService lemonService) { public , ID extends Serializable> LemonReactiveSecurityConfig lemonReactiveSecurityConfig( BlueTokenService blueTokenService, - LemonReactiveUserDetailsService userDetailsService) { + LemonReactiveUserDetailsService userDetailsService, + LemonProperties properties) { log.info("Configuring LemonReactiveSecurityConfig ..."); - return new LemonReactiveSecurityConfig(blueTokenService, userDetailsService); + return new LemonReactiveSecurityConfig(blueTokenService, userDetailsService, properties); } diff --git a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/security/LemonReactiveSecurityConfig.java b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/security/LemonReactiveSecurityConfig.java index 211a19ee..0a32a4ac 100644 --- a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/security/LemonReactiveSecurityConfig.java +++ b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/security/LemonReactiveSecurityConfig.java @@ -8,6 +8,7 @@ import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.security.web.server.authentication.WebFilterChainServerAuthenticationSuccessHandler; +import com.naturalprogrammer.spring.lemon.commons.LemonProperties; import com.naturalprogrammer.spring.lemon.commons.security.BlueTokenService; import com.naturalprogrammer.spring.lemon.commons.security.UserDto; import com.naturalprogrammer.spring.lemon.commonsreactive.security.LemonCommonsReactiveSecurityConfig; @@ -22,12 +23,16 @@ public class LemonReactiveSecurityConfig, ID ext private static final Log log = LogFactory.getLog(LemonReactiveSecurityConfig.class); protected LemonReactiveUserDetailsService userDetailsService; + private LemonProperties properties; public LemonReactiveSecurityConfig(BlueTokenService blueTokenService, - LemonReactiveUserDetailsService userDetailsService) { + LemonReactiveUserDetailsService userDetailsService, + LemonProperties properties) { super(blueTokenService); this.userDetailsService = userDetailsService; + this.properties = properties; + log.info("Created"); } @@ -57,7 +62,10 @@ protected String loginPage() { @Override protected void oauth2Login(ServerHttpSecurity http) { - http.oauth2Login(); // TODO: Configure properly + http.oauth2Login() + .authorizedClientRepository(new ReactiveCookieServerOAuth2AuthorizedClientRepository(properties)); + //.authenticationSuccessHandler(authenticationSuccessHandler); + //.authenticationManager(authenticationManager); } @Override diff --git a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/security/ReactiveCookieServerOAuth2AuthorizedClientRepository.java b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/security/ReactiveCookieServerOAuth2AuthorizedClientRepository.java new file mode 100644 index 00000000..9c3ba0e7 --- /dev/null +++ b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/security/ReactiveCookieServerOAuth2AuthorizedClientRepository.java @@ -0,0 +1,112 @@ +package com.naturalprogrammer.spring.lemonreactive.security; + +import java.util.Collections; + +import org.apache.commons.lang3.StringUtils; +import org.springframework.http.HttpCookie; +import org.springframework.http.ResponseCookie; +import org.springframework.http.server.reactive.ServerHttpResponse; +import org.springframework.security.core.Authentication; +import org.springframework.security.oauth2.client.OAuth2AuthorizedClient; +import org.springframework.security.oauth2.client.web.server.ServerOAuth2AuthorizedClientRepository; +import org.springframework.util.Assert; +import org.springframework.util.MultiValueMap; +import org.springframework.web.server.ServerWebExchange; + +import com.naturalprogrammer.spring.lemon.commons.LemonProperties; +import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; +import com.naturalprogrammer.spring.lemonreactive.util.LerUtils; + +import reactor.core.publisher.Mono; + +public class ReactiveCookieServerOAuth2AuthorizedClientRepository implements ServerOAuth2AuthorizedClientRepository { + + public static final String AUTHORIZATION_REQUEST_COOKIE_NAME = "lemon_oauth2_authorization_request"; + public static final String LEMON_REDIRECT_URI_COOKIE_PARAM_NAME = "lemon_redirect_uri"; + + private int cookieExpirySecs; + + public ReactiveCookieServerOAuth2AuthorizedClientRepository(LemonProperties properties) { + + cookieExpirySecs = properties.getJwt().getShortLivedMillis() / 1000; + } + + @Override + public Mono loadAuthorizedClient(String clientRegistrationId, + Authentication principal, ServerWebExchange exchange) { + + return LerUtils.fetchCookie(exchange, AUTHORIZATION_REQUEST_COOKIE_NAME) + .map(this::deserialize) + .orElse(Mono.empty()); + } + + @Override + public Mono saveAuthorizedClient(OAuth2AuthorizedClient authorizedClient, Authentication principal, + ServerWebExchange exchange) { + + ServerHttpResponse response = exchange.getResponse(); + + Assert.notNull(exchange, "exchange cannot be null"); + if (authorizedClient == null) { + + deleteCookies(exchange, AUTHORIZATION_REQUEST_COOKIE_NAME, LEMON_REDIRECT_URI_COOKIE_PARAM_NAME); + return Mono.empty(); + } + + ResponseCookie cookie = ResponseCookie + .from(AUTHORIZATION_REQUEST_COOKIE_NAME, LecUtils.serialize(authorizedClient)) + .path("/") + .httpOnly(true) + .maxAge(cookieExpirySecs) + .build(); + + response.addCookie(cookie); + + String lemonRedirectUri = exchange.getRequest() + .getQueryParams().getFirst(LEMON_REDIRECT_URI_COOKIE_PARAM_NAME); + + if (StringUtils.isNotBlank(lemonRedirectUri)) { + + cookie = ResponseCookie + .from(LEMON_REDIRECT_URI_COOKIE_PARAM_NAME, lemonRedirectUri) + .path("/") + .httpOnly(true) + .maxAge(cookieExpirySecs) + .build(); + + response.addCookie(cookie); + } + + return Mono.empty(); + } + + @Override + public Mono removeAuthorizedClient(String clientRegistrationId, Authentication principal, + ServerWebExchange exchange) { + + deleteCookies(exchange, AUTHORIZATION_REQUEST_COOKIE_NAME); + return Mono.empty(); + } + + private void deleteCookies(ServerWebExchange exchange, String ...cookiesToDelete) { + + MultiValueMap cookies = exchange.getRequest().getCookies(); + MultiValueMap responseCookies = exchange.getResponse().getCookies(); + + for (int i = 0; i < cookiesToDelete.length; i++) + if (cookies.getFirst(cookiesToDelete[i]) != null) { + + ResponseCookie cookie = ResponseCookie.from(cookiesToDelete[i], "") + .path("/") + .maxAge(0L) + .build(); + + responseCookies.put(cookiesToDelete[i], Collections.singletonList(cookie)); + }; + } + + private Mono deserialize(HttpCookie cookie) { + return Mono.just(LecUtils.deserialize(cookie.getValue())); + } + +} diff --git a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/util/LerUtils.java b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/util/LerUtils.java index 02b705e0..b1752551 100644 --- a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/util/LerUtils.java +++ b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/util/LerUtils.java @@ -1,9 +1,12 @@ package com.naturalprogrammer.spring.lemonreactive.util; import java.io.Serializable; +import java.util.Optional; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.springframework.http.HttpCookie; +import org.springframework.web.server.ServerWebExchange; import com.naturalprogrammer.spring.lemon.commons.security.LemonTokenService; import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; @@ -34,4 +37,8 @@ void ensureCredentialsUpToDate(JWTClaimsSet claims, U user) { LecUtils.ensureCredentials(issueTime >= user.getCredentialsUpdatedMillis(), "com.naturalprogrammer.spring.obsoleteToken"); } + + public static Optional fetchCookie(ServerWebExchange exchange, String cookieName) { + return Optional.ofNullable(exchange.getRequest().getCookies().getFirst(cookieName)); + } } From b780a44f5729ceb3f51791833a9c25c48f389cf2 Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Sun, 22 Sep 2019 07:57:30 +0530 Subject: [PATCH 095/116] ReactiveOauth plus AbstractLemonService halfway --- .../lemon/commons/AbstractLemonService.java | 180 ++++++++++++++++++ .../lemon/commons/domain/LemonUser.java | 16 ++ .../spring/lemon/LemonAutoConfiguration.java | 4 +- .../spring/lemon/LemonService.java | 142 +------------- .../spring/lemon/domain/AbstractUser.java | 4 +- .../security/LemonJpaSecurityConfig.java | 4 +- .../OAuth2AuthenticationSuccessHandler.java | 2 +- .../LemonReactiveAutoConfiguration.java | 22 ++- .../lemonreactive/LemonReactiveService.java | 159 +--------------- .../domain/AbstractMongoUser.java | 4 +- .../security/LemonReactiveSecurityConfig.java | 9 +- ...iveOAuth2AuthenticationSuccessHandler.java | 77 ++++++++ 12 files changed, 323 insertions(+), 300 deletions(-) create mode 100644 spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/AbstractLemonService.java create mode 100644 spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/domain/LemonUser.java create mode 100644 spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/security/ReactiveOAuth2AuthenticationSuccessHandler.java diff --git a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/AbstractLemonService.java b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/AbstractLemonService.java new file mode 100644 index 00000000..36c54789 --- /dev/null +++ b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/AbstractLemonService.java @@ -0,0 +1,180 @@ +package com.naturalprogrammer.spring.lemon.commons; + +import java.io.Serializable; +import java.util.HashMap; +import java.util.Map; + +import org.apache.commons.lang3.exception.ExceptionUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.springframework.boot.context.event.ApplicationReadyEvent; +import org.springframework.context.event.EventListener; +import org.springframework.security.crypto.password.PasswordEncoder; + +import com.naturalprogrammer.spring.lemon.commons.LemonProperties.Admin; +import com.naturalprogrammer.spring.lemon.commons.domain.LemonUser; +import com.naturalprogrammer.spring.lemon.commons.mail.LemonMailData; +import com.naturalprogrammer.spring.lemon.commons.mail.MailSender; +import com.naturalprogrammer.spring.lemon.commons.security.BlueTokenService; +import com.naturalprogrammer.spring.lemon.commons.security.GreenTokenService; +import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; +import com.naturalprogrammer.spring.lemon.commons.util.UserUtils; +import com.naturalprogrammer.spring.lemon.exceptions.util.LexUtils; + +public abstract class AbstractLemonService + , ID extends Serializable> { + + private static final Log log = LogFactory.getLog(AbstractLemonService.class); + protected PasswordEncoder passwordEncoder; + protected LemonProperties properties; + protected BlueTokenService blueTokenService; + protected GreenTokenService greenTokenService; + protected MailSender mailSender; + + /** + * This method is called after the application is ready. + * Needs to be public - otherwise Spring screams. + * + * @param event + */ + @EventListener + public void afterApplicationReady(ApplicationReadyEvent event) { + + log.info("Starting up Spring Lemon ..."); + onStartup(); // delegate to onStartup() + log.info("Spring Lemon started"); + } + + protected abstract void onStartup(); + + /** + * Creates the initial Admin user. + * Override this if needed. + */ + protected U createAdminUser() { + + // fetch data about the user to be created + Admin initialAdmin = properties.getAdmin(); + + log.info("Creating the first admin user: " + initialAdmin.getUsername()); + + // create the user + U user = newUser(); + user.setEmail(initialAdmin.getUsername()); + user.setPassword(passwordEncoder.encode( + properties.getAdmin().getPassword())); + user.getRoles().add(UserUtils.Role.ADMIN); + + return user; + } + + protected abstract U newUser(); + + protected Map buildContext() { + + // make the context + Map sharedProperties = new HashMap(2); + sharedProperties.put("reCaptchaSiteKey", properties.getRecaptcha().getSitekey()); + sharedProperties.put("shared", properties.getShared()); + + Map context = new HashMap<>(); + context.put("context", sharedProperties); + + return context; + } + + protected void initUser(U user) { + + log.debug("Initializing user: " + user); + + user.setPassword(passwordEncoder.encode(user.getPassword())); // encode the password + makeUnverified(user); // make the user unverified + } + + /** + * Makes a user unverified + */ + protected void makeUnverified(U user) { + + user.getRoles().add(UserUtils.Role.UNVERIFIED); + user.setCredentialsUpdatedMillis(System.currentTimeMillis()); + } + + /** + * Sends verification mail to a unverified user. + */ + protected void sendVerificationMail(final U user) { + try { + + log.debug("Sending verification mail to: " + user); + + String verificationCode = greenTokenService.createToken(GreenTokenService.VERIFY_AUDIENCE, + user.getId().toString(), properties.getJwt().getExpirationMillis(), + LecUtils.mapOf("email", user.getEmail())); + + // make the link + String verifyLink = properties.getApplicationUrl() + + "/users/" + user.getId() + "/verification?code=" + verificationCode; + + // send the mail + sendVerificationMail(user, verifyLink); + + log.debug("Verification mail to " + user.getEmail() + " queued."); + + } catch (Throwable e) { + // In case of exception, just log the error and keep silent + log.error(ExceptionUtils.getStackTrace(e)); + } + } + + /** + * Sends verification mail to a unverified user. + * Override this method if you're using a different MailData + */ + protected void sendVerificationMail(final U user, String verifyLink) { + + // send the mail + mailSender.send(LemonMailData.of(user.getEmail(), + LexUtils.getMessage("com.naturalprogrammer.spring.verifySubject"), + LexUtils.getMessage( + "com.naturalprogrammer.spring.verifyEmail", verifyLink))); + } + + /** + * Mails the forgot password link. + * + * @param user + */ + public void mailForgotPasswordLink(U user) { + + log.debug("Mailing forgot password link to user: " + user); + + String forgotPasswordCode = greenTokenService.createToken( + GreenTokenService.FORGOT_PASSWORD_AUDIENCE, + user.getEmail(), properties.getJwt().getExpirationMillis()); + + // make the link + String forgotPasswordLink = properties.getApplicationUrl() + + "/reset-password?code=" + forgotPasswordCode; + + mailForgotPasswordLink(user, forgotPasswordLink); + + log.debug("Forgot password link mail queued."); + } + + + /** + * Mails the forgot password link. + * + * Override this method if you're using a different MailData + */ + public void mailForgotPasswordLink(U user, String forgotPasswordLink) { + + // send the mail + mailSender.send(LemonMailData.of(user.getEmail(), + LexUtils.getMessage("com.naturalprogrammer.spring.forgotPasswordSubject"), + LexUtils.getMessage("com.naturalprogrammer.spring.forgotPasswordEmail", + forgotPasswordLink))); + } + +} diff --git a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/domain/LemonUser.java b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/domain/LemonUser.java new file mode 100644 index 00000000..b9f7aae9 --- /dev/null +++ b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/domain/LemonUser.java @@ -0,0 +1,16 @@ +package com.naturalprogrammer.spring.lemon.commons.domain; + +import java.io.Serializable; +import java.util.Set; + +public interface LemonUser { + + void setEmail(String username); + void setPassword(String password); + Set getRoles(); + String getPassword(); + void setCredentialsUpdatedMillis(long currentTimeMillis); + ID getId(); + String getEmail(); + +} diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/LemonAutoConfiguration.java b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/LemonAutoConfiguration.java index 6937e280..749b66b7 100644 --- a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/LemonAutoConfiguration.java +++ b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/LemonAutoConfiguration.java @@ -76,11 +76,11 @@ public LemonAuthenticationSuccessHandler authenticationSuccessHandler( */ @Bean @ConditionalOnMissingBean(OAuth2AuthenticationSuccessHandler.class) - public OAuth2AuthenticationSuccessHandler oauth2AuthenticationSuccessHandler( + public OAuth2AuthenticationSuccessHandler oauth2AuthenticationSuccessHandler( LemonProperties properties, BlueTokenService blueTokenService) { log.info("Configuring OAuth2AuthenticationSuccessHandler"); - return new OAuth2AuthenticationSuccessHandler<>(properties, blueTokenService); + return new OAuth2AuthenticationSuccessHandler(properties, blueTokenService); } /** diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/LemonService.java b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/LemonService.java index 2949295c..e11d764e 100644 --- a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/LemonService.java +++ b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/LemonService.java @@ -27,6 +27,7 @@ import org.springframework.transaction.annotation.Transactional; import org.springframework.validation.annotation.Validated; +import com.naturalprogrammer.spring.lemon.commons.AbstractLemonService; import com.naturalprogrammer.spring.lemon.commons.LemonProperties; import com.naturalprogrammer.spring.lemon.commons.LemonProperties.Admin; import com.naturalprogrammer.spring.lemon.commons.domain.ChangePasswordForm; @@ -55,17 +56,13 @@ @Validated @Transactional(propagation=Propagation.SUPPORTS, readOnly=true) public abstract class LemonService - , ID extends Serializable> { + , ID extends Serializable> + extends AbstractLemonService { private static final Log log = LogFactory.getLog(LemonService.class); - private LemonProperties properties; - private PasswordEncoder passwordEncoder; - private MailSender mailSender; private AbstractUserRepository userRepository; private UserDetailsService userDetailsService; - private BlueTokenService blueTokenService; - private GreenTokenService greenTokenService; @Autowired public void createLemonService(LemonProperties properties, @@ -88,21 +85,6 @@ public void createLemonService(LemonProperties properties, } - /** - * This method is called after the application is ready. - * Needs to be public - otherwise Spring screams. - * - * @param event - */ - @EventListener - public void afterApplicationReady(ApplicationReadyEvent event) { - - log.info("Starting up Spring Lemon ..."); - onStartup(); // delegate to onStartup() - log.info("Spring Lemon started"); - } - - /** * Creates the initial Admin user, if not found. * Override this method if needed. @@ -125,28 +107,6 @@ public void onStartup() { } - /** - * Creates the initial Admin user. - * Override this if needed. - */ - protected U createAdminUser() { - - // fetch data about the user to be created - Admin initialAdmin = properties.getAdmin(); - - log.info("Creating the first admin user: " + initialAdmin.getUsername()); - - // create the user - U user = newUser(); - user.setEmail(initialAdmin.getUsername()); - user.setPassword(passwordEncoder.encode( - properties.getAdmin().getPassword())); - user.getRoles().add(UserUtils.Role.ADMIN); - - return user; - } - - /** * Creates a new user object. Must be overridden in the * subclass, like this: @@ -178,19 +138,16 @@ public Map getContext(Optional expirationMillis, HttpServl log.debug("Getting context ..."); - // make the context - Map sharedProperties = new HashMap(2); - sharedProperties.put("reCaptchaSiteKey", properties.getRecaptcha().getSitekey()); - sharedProperties.put("shared", properties.getShared()); + Map context = buildContext(); UserDto currentUser = LecwUtils.currentUser(); - if (currentUser != null) + if (currentUser != null) { addAuthHeader(response, currentUser.getUsername(), expirationMillis.orElse(properties.getJwt().getExpirationMillis())); + context.put("user", currentUser); + } - return LecUtils.mapOf( - "context", sharedProperties, - "user", LecwUtils.currentUser()); + return context; } @@ -233,55 +190,11 @@ protected void initUser(U user) { */ protected void makeUnverified(U user) { - user.getRoles().add(UserUtils.Role.UNVERIFIED); - user.setCredentialsUpdatedMillis(System.currentTimeMillis()); + super.makeUnverified(user); LecjUtils.afterCommit(() -> sendVerificationMail(user)); // send a verification mail to the user } - /** - * Sends verification mail to a unverified user. - */ - protected void sendVerificationMail(final U user) { - try { - - log.debug("Sending verification mail to: " + user); - - String verificationCode = greenTokenService.createToken( - GreenTokenService.VERIFY_AUDIENCE, - user.getId().toString(), properties.getJwt().getExpirationMillis(), - LecUtils.mapOf("email", user.getEmail())); - - // make the link - String verifyLink = properties.getApplicationUrl() - + "/users/" + user.getId() + "/verification?code=" + verificationCode; - - // send the mail - sendVerificationMail(user, verifyLink); - - log.debug("Verification mail to " + user.getEmail() + " queued."); - - } catch (Throwable e) { - // In case of exception, just log the error and keep silent - log.error(ExceptionUtils.getStackTrace(e)); - } - } - - - /** - * Sends verification mail to a unverified user. - * Override this method if you're using a different MailData - */ - protected void sendVerificationMail(final U user, String verifyLink) { - - // send the mail - mailSender.send(LemonMailData.of(user.getEmail(), - LexUtils.getMessage("com.naturalprogrammer.spring.verifySubject"), - LexUtils.getMessage( - "com.naturalprogrammer.spring.verifyEmail", verifyLink))); - } - - /** * Resends verification mail to the user. */ @@ -381,43 +294,6 @@ public void forgotPassword(@Valid @Email @NotBlank String email) { } - /** - * Mails the forgot password link. - * - * @param user - */ - public void mailForgotPasswordLink(U user) { - - log.debug("Mailing forgot password link to user: " + user); - - String forgotPasswordCode = greenTokenService.createToken( - GreenTokenService.FORGOT_PASSWORD_AUDIENCE, - user.getEmail(), properties.getJwt().getExpirationMillis()); - - // make the link - String forgotPasswordLink = properties.getApplicationUrl() - + "/reset-password?code=" + forgotPasswordCode; - - mailForgotPasswordLink(user, forgotPasswordLink); - - log.debug("Forgot password link mail queued."); - } - - - /** - * Mails the forgot password link. - * - * Override this method if you're using a different MailData - */ - public void mailForgotPasswordLink(U user, String forgotPasswordLink) { - - // send the mail - mailSender.send(LemonMailData.of(user.getEmail(), - LexUtils.getMessage("com.naturalprogrammer.spring.forgotPasswordSubject"), - LexUtils.getMessage("com.naturalprogrammer.spring.forgotPasswordEmail", - forgotPasswordLink))); - } - /** * Resets the password. */ diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/domain/AbstractUser.java b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/domain/AbstractUser.java index 8aaa80f8..4e1b4724 100644 --- a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/domain/AbstractUser.java +++ b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/domain/AbstractUser.java @@ -14,6 +14,7 @@ import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonView; +import com.naturalprogrammer.spring.lemon.commons.domain.LemonUser; import com.naturalprogrammer.spring.lemon.commons.security.UserDto; import com.naturalprogrammer.spring.lemon.commons.util.UserUtils; import com.naturalprogrammer.spring.lemon.commons.validation.Captcha; @@ -33,7 +34,8 @@ @Getter @Setter @MappedSuperclass public class AbstractUser -extends LemonEntity { + extends LemonEntity + implements LemonUser { // email @JsonView(UserUtils.SignupInput.class) diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonJpaSecurityConfig.java b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonJpaSecurityConfig.java index ab00714a..39534755 100644 --- a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonJpaSecurityConfig.java +++ b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonJpaSecurityConfig.java @@ -26,7 +26,7 @@ public class LemonJpaSecurityConfig extends LemonWebSecurityConfig { private LemonAuthenticationSuccessHandler authenticationSuccessHandler; private LemonOidcUserService oidcUserService; private LemonOAuth2UserService oauth2UserService; - private OAuth2AuthenticationSuccessHandler oauth2AuthenticationSuccessHandler; + private OAuth2AuthenticationSuccessHandler oauth2AuthenticationSuccessHandler; private OAuth2AuthenticationFailureHandler oauth2AuthenticationFailureHandler; @Autowired @@ -34,7 +34,7 @@ public void createLemonSecurityConfig(LemonProperties properties, LemonUserDetai LemonAuthenticationSuccessHandler authenticationSuccessHandler, LemonOidcUserService oidcUserService, LemonOAuth2UserService oauth2UserService, - OAuth2AuthenticationSuccessHandler oauth2AuthenticationSuccessHandler, + OAuth2AuthenticationSuccessHandler oauth2AuthenticationSuccessHandler, OAuth2AuthenticationFailureHandler oauth2AuthenticationFailureHandler) { this.properties = properties; diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/OAuth2AuthenticationSuccessHandler.java b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/OAuth2AuthenticationSuccessHandler.java index 57f36c84..4757eaa2 100644 --- a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/OAuth2AuthenticationSuccessHandler.java +++ b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/OAuth2AuthenticationSuccessHandler.java @@ -24,7 +24,7 @@ * @author Sanjay Patel */ @AllArgsConstructor -public class OAuth2AuthenticationSuccessHandler +public class OAuth2AuthenticationSuccessHandler extends SimpleUrlAuthenticationSuccessHandler { private static final Log log = LogFactory.getLog(OAuth2AuthenticationSuccessHandler.class); diff --git a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveAutoConfiguration.java b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveAutoConfiguration.java index 102f994b..8bcad0a9 100644 --- a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveAutoConfiguration.java +++ b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveAutoConfiguration.java @@ -20,6 +20,7 @@ import com.naturalprogrammer.spring.lemonreactive.domain.AbstractMongoUserRepository; import com.naturalprogrammer.spring.lemonreactive.security.LemonReactiveSecurityConfig; import com.naturalprogrammer.spring.lemonreactive.security.LemonReactiveUserDetailsService; +import com.naturalprogrammer.spring.lemonreactive.security.ReactiveOAuth2AuthenticationSuccessHandler; import com.naturalprogrammer.spring.lemonreactive.util.LerUtils; @Configuration @@ -41,17 +42,36 @@ IdConverter idConverter(LemonReactiveService lemonService) { return id -> lemonService.toId(id); } + @Bean + @ConditionalOnMissingBean(ReactiveOAuth2AuthenticationSuccessHandler.class) + public , ID extends Serializable> + ReactiveOAuth2AuthenticationSuccessHandler reactiveOAuth2AuthenticationSuccessHandler( + BlueTokenService blueTokenService, + LemonProperties properties) { + + log.info("Configuring ReactiveOAuth2AuthenticationSuccessHandler ..."); + + return new ReactiveOAuth2AuthenticationSuccessHandler( + blueTokenService, + properties); + } + @Bean @ConditionalOnMissingBean(LemonReactiveSecurityConfig.class) public , ID extends Serializable> LemonReactiveSecurityConfig lemonReactiveSecurityConfig( BlueTokenService blueTokenService, LemonReactiveUserDetailsService userDetailsService, + ReactiveOAuth2AuthenticationSuccessHandler reactiveOAuth2AuthenticationSuccessHandler, LemonProperties properties) { log.info("Configuring LemonReactiveSecurityConfig ..."); - return new LemonReactiveSecurityConfig(blueTokenService, userDetailsService, properties); + return new LemonReactiveSecurityConfig( + blueTokenService, + userDetailsService, + reactiveOAuth2AuthenticationSuccessHandler, + properties); } diff --git a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveService.java b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveService.java index 3c91aa0d..fb502960 100644 --- a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveService.java +++ b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveService.java @@ -21,6 +21,7 @@ import org.springframework.util.MultiValueMap; import org.springframework.web.server.ServerWebExchange; +import com.naturalprogrammer.spring.lemon.commons.AbstractLemonService; import com.naturalprogrammer.spring.lemon.commons.LemonProperties; import com.naturalprogrammer.spring.lemon.commons.LemonProperties.Admin; import com.naturalprogrammer.spring.lemon.commons.domain.ChangePasswordForm; @@ -47,17 +48,13 @@ import reactor.util.function.Tuples; public abstract class LemonReactiveService - , ID extends Serializable> { + , ID extends Serializable> + extends AbstractLemonService { private static final Log log = LogFactory.getLog(LemonReactiveService.class); - protected LemonProperties properties; - protected PasswordEncoder passwordEncoder; - protected MailSender mailSender; protected AbstractMongoUserRepository userRepository; protected ReactiveUserDetailsService userDetailsService; - protected BlueTokenService blueTokenService; - protected GreenTokenService greenTokenService; @Autowired public void createLemonService(LemonProperties properties, @@ -80,21 +77,6 @@ public void createLemonService(LemonProperties properties, } - /** - * This method is called after the application is ready. - * Needs to be public - otherwise Spring screams. - * - * @param event - */ - @EventListener - public void afterApplicationReady(ApplicationReadyEvent event) { - - log.info("Starting up Spring Lemon ..."); - onStartup(); // delegate to onStartup() - log.info("Spring Lemon started"); - } - - public void onStartup() { userDetailsService @@ -111,28 +93,6 @@ public void onStartup() { } - /** - * Creates the initial Admin user. - * Override this if needed. - */ - protected U createAdminUser() { - - // fetch data about the user to be created - Admin initialAdmin = properties.getAdmin(); - - log.info("Creating the first admin user: " + initialAdmin.getUsername()); - - // create the user - U user = newUser(); - user.setEmail(initialAdmin.getUsername()); - user.setPassword(passwordEncoder.encode( - properties.getAdmin().getPassword())); - user.getRoles().add(UserUtils.Role.ADMIN); - - return user; - } - - /** * Creates a new user object. Must be overridden in the * subclass, like this: @@ -179,20 +139,6 @@ public Mono> getContext(Optional expirationMillis, Ser } - protected Map buildContext() { - - // make the context - Map sharedProperties = new HashMap(2); - sharedProperties.put("reCaptchaSiteKey", properties.getRecaptcha().getSitekey()); - sharedProperties.put("shared", properties.getShared()); - - Map context = new HashMap<>(); - context.put("context", sharedProperties); - - return context; - } - - /** * Signs up a user. */ @@ -209,67 +155,6 @@ public Mono signup(Mono user) { } - protected void initUser(U user) { - - log.debug("Initializing user: " + user); - - user.setPassword(passwordEncoder.encode(user.getPassword())); // encode the password - makeUnverified(user); // make the user unverified - } - - - /** - * Makes a user unverified - */ - protected void makeUnverified(U user) { - - user.getRoles().add(UserUtils.Role.UNVERIFIED); - user.setCredentialsUpdatedMillis(System.currentTimeMillis()); - } - - - /** - * Sends verification mail to a unverified user. - */ - protected void sendVerificationMail(final U user) { - try { - - log.debug("Sending verification mail to: " + user); - - String verificationCode = greenTokenService.createToken(GreenTokenService.VERIFY_AUDIENCE, - user.getId().toString(), properties.getJwt().getExpirationMillis(), - LecUtils.mapOf("email", user.getEmail())); - - // make the link - String verifyLink = properties.getApplicationUrl() - + "/users/" + user.getId() + "/verification?code=" + verificationCode; - - // send the mail - sendVerificationMail(user, verifyLink); - - log.debug("Verification mail to " + user.getEmail() + " queued."); - - } catch (Throwable e) { - // In case of exception, just log the error and keep silent - log.error(ExceptionUtils.getStackTrace(e)); - } - } - - - /** - * Sends verification mail to a unverified user. - * Override this method if you're using a different MailData - */ - protected void sendVerificationMail(final U user, String verifyLink) { - - // send the mail - mailSender.send(LemonMailData.of(user.getEmail(), - LexUtils.getMessage("com.naturalprogrammer.spring.verifySubject"), - LexUtils.getMessage( - "com.naturalprogrammer.spring.verifyEmail", verifyLink))); - } - - /** * Resends verification mail to the user. */ @@ -358,44 +243,6 @@ public Mono forgotPassword(Mono> formData) { } - /** - * Mails the forgot password link. - * - * @param user - */ - public void mailForgotPasswordLink(U user) { - - log.debug("Mailing forgot password link to user: " + user); - - String forgotPasswordCode = greenTokenService.createToken( - GreenTokenService.FORGOT_PASSWORD_AUDIENCE, - user.getEmail(), properties.getJwt().getExpirationMillis()); - - // make the link - String forgotPasswordLink = properties.getApplicationUrl() - + "/reset-password?code=" + forgotPasswordCode; - - mailForgotPasswordLink(user, forgotPasswordLink); - - log.debug("Forgot password link mail queued."); - } - - - /** - * Mails the forgot password link. - * - * Override this method if you're using a different MailData - */ - public void mailForgotPasswordLink(U user, String forgotPasswordLink) { - - // send the mail - mailSender.send(LemonMailData.of(user.getEmail(), - LexUtils.getMessage("com.naturalprogrammer.spring.forgotPasswordSubject"), - LexUtils.getMessage("com.naturalprogrammer.spring.forgotPasswordEmail", - forgotPasswordLink))); - } - - public Mono resetPassword(Mono resetPasswordForm) { return resetPasswordForm.map(form -> { diff --git a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/domain/AbstractMongoUser.java b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/domain/AbstractMongoUser.java index 20e56f0d..d778c226 100644 --- a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/domain/AbstractMongoUser.java +++ b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/domain/AbstractMongoUser.java @@ -10,6 +10,7 @@ import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonView; +import com.naturalprogrammer.spring.lemon.commons.domain.LemonUser; import com.naturalprogrammer.spring.lemon.commons.security.UserDto; import com.naturalprogrammer.spring.lemon.commons.util.UserUtils; import com.naturalprogrammer.spring.lemon.commons.validation.Captcha; @@ -23,7 +24,8 @@ @Getter @Setter public abstract class AbstractMongoUser - extends AbstractDocument implements CredentialsContainer { + extends AbstractDocument + implements CredentialsContainer, LemonUser { // email @JsonView(UserUtils.SignupInput.class) diff --git a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/security/LemonReactiveSecurityConfig.java b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/security/LemonReactiveSecurityConfig.java index 0a32a4ac..7b004e03 100644 --- a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/security/LemonReactiveSecurityConfig.java +++ b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/security/LemonReactiveSecurityConfig.java @@ -24,13 +24,16 @@ public class LemonReactiveSecurityConfig, ID ext protected LemonReactiveUserDetailsService userDetailsService; private LemonProperties properties; + private ReactiveOAuth2AuthenticationSuccessHandler reactiveOAuth2AuthenticationSuccessHandler; public LemonReactiveSecurityConfig(BlueTokenService blueTokenService, LemonReactiveUserDetailsService userDetailsService, + ReactiveOAuth2AuthenticationSuccessHandler reactiveOAuth2AuthenticationSuccessHandler, LemonProperties properties) { super(blueTokenService); this.userDetailsService = userDetailsService; + this.reactiveOAuth2AuthenticationSuccessHandler = reactiveOAuth2AuthenticationSuccessHandler; this.properties = properties; log.info("Created"); @@ -63,9 +66,9 @@ protected String loginPage() { protected void oauth2Login(ServerHttpSecurity http) { http.oauth2Login() - .authorizedClientRepository(new ReactiveCookieServerOAuth2AuthorizedClientRepository(properties)); - //.authenticationSuccessHandler(authenticationSuccessHandler); - //.authenticationManager(authenticationManager); + .authorizedClientRepository(new ReactiveCookieServerOAuth2AuthorizedClientRepository(properties)) + .authenticationSuccessHandler(reactiveOAuth2AuthenticationSuccessHandler) + .authenticationManager(authenticationManager); } @Override diff --git a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/security/ReactiveOAuth2AuthenticationSuccessHandler.java b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/security/ReactiveOAuth2AuthenticationSuccessHandler.java new file mode 100644 index 00000000..caf8db58 --- /dev/null +++ b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/security/ReactiveOAuth2AuthenticationSuccessHandler.java @@ -0,0 +1,77 @@ +package com.naturalprogrammer.spring.lemonreactive.security; + +import java.io.Serializable; +import java.net.URI; +import java.util.Optional; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.ReactiveSecurityContextHolder; +import org.springframework.security.oauth2.client.authentication.OAuth2LoginAuthenticationToken; +import org.springframework.security.oauth2.core.user.OAuth2User; +import org.springframework.security.web.server.DefaultServerRedirectStrategy; +import org.springframework.security.web.server.ServerRedirectStrategy; +import org.springframework.security.web.server.WebFilterExchange; +import org.springframework.security.web.server.authentication.ServerAuthenticationSuccessHandler; +import org.springframework.web.server.ServerWebExchange; + +import com.naturalprogrammer.spring.lemon.commons.LemonProperties; +import com.naturalprogrammer.spring.lemon.commons.security.BlueTokenService; +import com.naturalprogrammer.spring.lemon.commons.security.LemonPrincipal; +import com.naturalprogrammer.spring.lemon.commons.security.UserDto; +import com.naturalprogrammer.spring.lemon.commonsreactive.util.LecrUtils; + +import lombok.AllArgsConstructor; +import reactor.core.publisher.Mono; + +/** + * Authentication success handler for redirecting the + * OAuth2 signed in user to a URL with a short lived auth token + * + * @author Sanjay Patel + */ +@AllArgsConstructor +public class ReactiveOAuth2AuthenticationSuccessHandler + implements ServerAuthenticationSuccessHandler { + + private static final Log log = LogFactory.getLog(ReactiveOAuth2AuthenticationSuccessHandler.class); + private static final ServerRedirectStrategy redirectStrategy = new DefaultServerRedirectStrategy(); + + private BlueTokenService blueTokenService; + private LemonProperties properties; + + @Override + public Mono onAuthenticationSuccess(WebFilterExchange webFilterExchange, + Authentication authentication) { + + ServerWebExchange exchange = webFilterExchange.getExchange(); + + return ReactiveSecurityContextHolder.getContext() + .cast(OAuth2LoginAuthenticationToken.class) + .map(this::toLemonPrincipal) + .map(LemonPrincipal::currentUser) + .map(this::getAuthToken) + .map(URI::create) + .flatMap(location -> redirectStrategy.sendRedirect(exchange, location)); + } + + private LemonPrincipal toLemonPrincipal(OAuth2LoginAuthenticationToken token) { + + String registrationId = token.getClientRegistration().getRegistrationId(); + OAuth2User principal = token.getPrincipal(); + + return new LemonPrincipal(); + + } + + private String getAuthToken(UserDto user) { + + String shortLivedAuthToken = blueTokenService.createToken( + BlueTokenService.AUTH_AUDIENCE, + user.getUsername(), + (long) properties.getJwt().getShortLivedMillis()); + + return shortLivedAuthToken; + } +} From 0d826072adec03b3e5c4f810540a59dc5fcaed06 Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Sun, 22 Sep 2019 14:43:04 +0530 Subject: [PATCH 096/116] Spring Reactive OAuth Login starts working --- .../lemon/commonsreactive/util/LecrUtils.java | 6 ++ .../lemon/commons/AbstractLemonService.java | 36 ++++++++ .../spring/lemon/commons/util/LecUtils.java | 3 + .../spring/lemon/LemonService.java | 36 -------- ...eOAuth2AuthorizationRequestRepository.java | 15 ++-- .../OAuth2AuthenticationFailureHandler.java | 6 +- .../OAuth2AuthenticationSuccessHandler.java | 9 +- .../LemonReactiveAutoConfiguration.java | 18 +++- .../security/LemonReactiveSecurityConfig.java | 18 +++- ...erverOAuth2AuthorizedClientRepository.java | 19 ++-- ...iveOAuth2AuthenticationSuccessHandler.java | 87 ++++++++++++++++--- .../spring/lemonreactive/util/LerUtils.java | 7 -- 12 files changed, 173 insertions(+), 87 deletions(-) diff --git a/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/util/LecrUtils.java b/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/util/LecrUtils.java index 5d22fca6..9af9288a 100644 --- a/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/util/LecrUtils.java +++ b/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/util/LecrUtils.java @@ -8,7 +8,9 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.springframework.http.HttpCookie; import org.springframework.security.core.context.ReactiveSecurityContextHolder; +import org.springframework.web.server.ServerWebExchange; import com.github.fge.jsonpatch.JsonPatchException; import com.naturalprogrammer.spring.lemon.commons.security.UserDto; @@ -33,6 +35,10 @@ public void postConstruct() { NOT_FOUND_MONO = Mono.error(LexUtils.NOT_FOUND_EXCEPTION); } + public static Optional fetchCookie(ServerWebExchange exchange, String cookieName) { + return Optional.ofNullable(exchange.getRequest().getCookies().getFirst(cookieName)); + } + /** * Gets the current-user */ diff --git a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/AbstractLemonService.java b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/AbstractLemonService.java index 36c54789..d55be212 100644 --- a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/AbstractLemonService.java +++ b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/AbstractLemonService.java @@ -10,6 +10,7 @@ import org.springframework.boot.context.event.ApplicationReadyEvent; import org.springframework.context.event.EventListener; import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.security.oauth2.core.oidc.StandardClaimNames; import com.naturalprogrammer.spring.lemon.commons.LemonProperties.Admin; import com.naturalprogrammer.spring.lemon.commons.domain.LemonUser; @@ -176,5 +177,40 @@ public void mailForgotPasswordLink(U user, String forgotPasswordLink) { LexUtils.getMessage("com.naturalprogrammer.spring.forgotPasswordEmail", forgotPasswordLink))); } + + /** + * Extracts the email id from user attributes received from OAuth2 provider, e.g. Google + * + */ + public String getOAuth2Email(String registrationId, Map attributes) { + + return (String) attributes.get(StandardClaimNames.EMAIL); + } + + + /** + * Extracts additional fields, e.g. name from user attributes received from OAuth2 provider, e.g. Google + * Override this if you introduce more user fields, e.g. name + */ + public void fillAdditionalFields(String clientId, U user, Map attributes) { + + } + + + /** + * Checks if the account at the OAuth2 provider is verified + */ + public boolean getOAuth2AccountVerified(String registrationId, Map attributes) { + + Object verified = attributes.get(StandardClaimNames.EMAIL_VERIFIED); + if (verified == null) + verified = attributes.get("verified"); + + try { + return (boolean) verified; + } catch (Throwable t) { + return false; + } + } } diff --git a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/util/LecUtils.java b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/util/LecUtils.java index 3c3b1ed3..a75c56b7 100644 --- a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/util/LecUtils.java +++ b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/util/LecUtils.java @@ -40,6 +40,9 @@ public class LecUtils { private static final Log log = LogFactory.getLog(LecUtils.class); + public static final String AUTHORIZATION_REQUEST_COOKIE_NAME = "lemon_oauth2_authorization_request"; + public static final String LEMON_REDIRECT_URI_COOKIE_PARAM_NAME = "lemon_redirect_uri"; + // Computed authorities public static final String GOOD_ADMIN = "GOOD_ADMIN"; public static final String GOOD_USER = "GOOD_USER"; diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/LemonService.java b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/LemonService.java index e11d764e..66014dd5 100644 --- a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/LemonService.java +++ b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/LemonService.java @@ -556,42 +556,6 @@ public void changeEmail(ID userId, @Valid @NotBlank String changeEmailCode) { } - /** - * Extracts the email id from user attributes received from OAuth2 provider, e.g. Google - * - */ - public String getOAuth2Email(String registrationId, Map attributes) { - - return (String) attributes.get(StandardClaimNames.EMAIL); - } - - - /** - * Extracts additional fields, e.g. name from user attributes received from OAuth2 provider, e.g. Google - * Override this if you introduce more user fields, e.g. name - */ - public void fillAdditionalFields(String clientId, U user, Map attributes) { - - } - - - /** - * Checks if the account at the OAuth2 provider is verified - */ - public boolean getOAuth2AccountVerified(String registrationId, Map attributes) { - - Object verified = attributes.get(StandardClaimNames.EMAIL_VERIFIED); - if (verified == null) - verified = attributes.get("verified"); - - try { - return (boolean) verified; - } catch (Throwable t) { - return false; - } - } - - /** * Fetches a new token - for session scrolling etc. * @return diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/HttpCookieOAuth2AuthorizationRequestRepository.java b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/HttpCookieOAuth2AuthorizationRequestRepository.java index 54734448..00939ea8 100644 --- a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/HttpCookieOAuth2AuthorizationRequestRepository.java +++ b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/HttpCookieOAuth2AuthorizationRequestRepository.java @@ -19,9 +19,6 @@ */ public class HttpCookieOAuth2AuthorizationRequestRepository implements AuthorizationRequestRepository { - public static final String AUTHORIZATION_REQUEST_COOKIE_NAME = "lemon_oauth2_authorization_request"; - public static final String LEMON_REDIRECT_URI_COOKIE_PARAM_NAME = "lemon_redirect_uri"; - private int cookieExpirySecs; public HttpCookieOAuth2AuthorizationRequestRepository(LemonProperties properties) { @@ -37,7 +34,7 @@ public OAuth2AuthorizationRequest loadAuthorizationRequest(HttpServletRequest re Assert.notNull(request, "request cannot be null"); - return LecwUtils.fetchCookie(request, AUTHORIZATION_REQUEST_COOKIE_NAME) + return LecwUtils.fetchCookie(request, LecUtils.AUTHORIZATION_REQUEST_COOKIE_NAME) .map(this::deserialize) .orElse(null); } @@ -54,20 +51,20 @@ public void saveAuthorizationRequest(OAuth2AuthorizationRequest authorizationReq if (authorizationRequest == null) { - deleteCookies(request, response, AUTHORIZATION_REQUEST_COOKIE_NAME, LEMON_REDIRECT_URI_COOKIE_PARAM_NAME); + deleteCookies(request, response, LecUtils.AUTHORIZATION_REQUEST_COOKIE_NAME, LecUtils.LEMON_REDIRECT_URI_COOKIE_PARAM_NAME); return; } - Cookie cookie = new Cookie(AUTHORIZATION_REQUEST_COOKIE_NAME, LecUtils.serialize(authorizationRequest)); + Cookie cookie = new Cookie(LecUtils.AUTHORIZATION_REQUEST_COOKIE_NAME, LecUtils.serialize(authorizationRequest)); cookie.setPath("/"); cookie.setHttpOnly(true); cookie.setMaxAge(cookieExpirySecs); response.addCookie(cookie); - String lemonRedirectUri = request.getParameter(LEMON_REDIRECT_URI_COOKIE_PARAM_NAME); + String lemonRedirectUri = request.getParameter(LecUtils.LEMON_REDIRECT_URI_COOKIE_PARAM_NAME); if (StringUtils.isNotBlank(lemonRedirectUri)) { - cookie = new Cookie(LEMON_REDIRECT_URI_COOKIE_PARAM_NAME, lemonRedirectUri); + cookie = new Cookie(LecUtils.LEMON_REDIRECT_URI_COOKIE_PARAM_NAME, lemonRedirectUri); cookie.setPath("/"); cookie.setHttpOnly(true); cookie.setMaxAge(cookieExpirySecs); @@ -79,7 +76,7 @@ public void saveAuthorizationRequest(OAuth2AuthorizationRequest authorizationReq public OAuth2AuthorizationRequest removeAuthorizationRequest(HttpServletRequest request, HttpServletResponse response) { OAuth2AuthorizationRequest originalRequest = loadAuthorizationRequest(request); - deleteCookies(request, response, AUTHORIZATION_REQUEST_COOKIE_NAME); + deleteCookies(request, response, LecUtils.AUTHORIZATION_REQUEST_COOKIE_NAME); return originalRequest; } diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/OAuth2AuthenticationFailureHandler.java b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/OAuth2AuthenticationFailureHandler.java index c7b5667f..15ba9343 100644 --- a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/OAuth2AuthenticationFailureHandler.java +++ b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/OAuth2AuthenticationFailureHandler.java @@ -9,6 +9,8 @@ import org.springframework.security.core.AuthenticationException; import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler; +import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; + /** * OAuth2 Authentication failure handler for removing oauth2 related cookies * @@ -23,8 +25,8 @@ public void onAuthenticationFailure(HttpServletRequest request, throws IOException, ServletException { HttpCookieOAuth2AuthorizationRequestRepository.deleteCookies(request, response, - HttpCookieOAuth2AuthorizationRequestRepository.AUTHORIZATION_REQUEST_COOKIE_NAME, - HttpCookieOAuth2AuthorizationRequestRepository.LEMON_REDIRECT_URI_COOKIE_PARAM_NAME); + LecUtils.AUTHORIZATION_REQUEST_COOKIE_NAME, + LecUtils.LEMON_REDIRECT_URI_COOKIE_PARAM_NAME); super.onAuthenticationFailure(request, response, exception); } diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/OAuth2AuthenticationSuccessHandler.java b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/OAuth2AuthenticationSuccessHandler.java index 4757eaa2..c9734664 100644 --- a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/OAuth2AuthenticationSuccessHandler.java +++ b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/OAuth2AuthenticationSuccessHandler.java @@ -1,7 +1,5 @@ package com.naturalprogrammer.spring.lemon.security; -import java.io.Serializable; - import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @@ -13,6 +11,7 @@ import com.naturalprogrammer.spring.lemon.commons.LemonProperties; import com.naturalprogrammer.spring.lemon.commons.security.BlueTokenService; import com.naturalprogrammer.spring.lemon.commons.security.UserDto; +import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; import com.naturalprogrammer.spring.lemon.commonsweb.util.LecwUtils; import lombok.AllArgsConstructor; @@ -44,13 +43,13 @@ protected String determineTargetUrl(HttpServletRequest request, (long) properties.getJwt().getShortLivedMillis()); String targetUrl = LecwUtils.fetchCookie(request, - HttpCookieOAuth2AuthorizationRequestRepository.LEMON_REDIRECT_URI_COOKIE_PARAM_NAME) + LecUtils.LEMON_REDIRECT_URI_COOKIE_PARAM_NAME) .map(Cookie::getValue) .orElse(properties.getOauth2AuthenticationSuccessUrl()); HttpCookieOAuth2AuthorizationRequestRepository.deleteCookies(request, response, - HttpCookieOAuth2AuthorizationRequestRepository.AUTHORIZATION_REQUEST_COOKIE_NAME, - HttpCookieOAuth2AuthorizationRequestRepository.LEMON_REDIRECT_URI_COOKIE_PARAM_NAME); + LecUtils.AUTHORIZATION_REQUEST_COOKIE_NAME, + LecUtils.LEMON_REDIRECT_URI_COOKIE_PARAM_NAME); return targetUrl + shortLivedAuthToken; } diff --git a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveAutoConfiguration.java b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveAutoConfiguration.java index 8bcad0a9..7f15c203 100644 --- a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveAutoConfiguration.java +++ b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveAutoConfiguration.java @@ -10,6 +10,7 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.crypto.password.PasswordEncoder; import com.naturalprogrammer.spring.lemon.commons.LemonProperties; import com.naturalprogrammer.spring.lemon.commons.domain.IdConverter; @@ -45,14 +46,23 @@ IdConverter idConverter(LemonReactiveService lemonService) { @Bean @ConditionalOnMissingBean(ReactiveOAuth2AuthenticationSuccessHandler.class) public , ID extends Serializable> - ReactiveOAuth2AuthenticationSuccessHandler reactiveOAuth2AuthenticationSuccessHandler( + ReactiveOAuth2AuthenticationSuccessHandler reactiveOAuth2AuthenticationSuccessHandler( BlueTokenService blueTokenService, - LemonProperties properties) { + AbstractMongoUserRepository userRepository, + LemonReactiveUserDetailsService userDetailsService, + LemonReactiveService lemonService, + PasswordEncoder passwordEncoder, + LemonProperties properties +) { log.info("Configuring ReactiveOAuth2AuthenticationSuccessHandler ..."); - return new ReactiveOAuth2AuthenticationSuccessHandler( + return new ReactiveOAuth2AuthenticationSuccessHandler( blueTokenService, + userRepository, + userDetailsService, + lemonService, + passwordEncoder, properties); } @@ -62,7 +72,7 @@ ReactiveOAuth2AuthenticationSuccessHandler reactiveOAuth2AuthenticationSuccessHa LemonReactiveSecurityConfig lemonReactiveSecurityConfig( BlueTokenService blueTokenService, LemonReactiveUserDetailsService userDetailsService, - ReactiveOAuth2AuthenticationSuccessHandler reactiveOAuth2AuthenticationSuccessHandler, + ReactiveOAuth2AuthenticationSuccessHandler reactiveOAuth2AuthenticationSuccessHandler, LemonProperties properties) { log.info("Configuring LemonReactiveSecurityConfig ..."); diff --git a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/security/LemonReactiveSecurityConfig.java b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/security/LemonReactiveSecurityConfig.java index 7b004e03..517e96ef 100644 --- a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/security/LemonReactiveSecurityConfig.java +++ b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/security/LemonReactiveSecurityConfig.java @@ -5,12 +5,15 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.security.config.web.server.ServerHttpSecurity; +import org.springframework.security.core.AuthenticationException; import org.springframework.security.core.userdetails.UsernameNotFoundException; +import org.springframework.security.web.server.WebFilterExchange; import org.springframework.security.web.server.authentication.WebFilterChainServerAuthenticationSuccessHandler; import com.naturalprogrammer.spring.lemon.commons.LemonProperties; import com.naturalprogrammer.spring.lemon.commons.security.BlueTokenService; import com.naturalprogrammer.spring.lemon.commons.security.UserDto; +import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; import com.naturalprogrammer.spring.lemon.commonsreactive.security.LemonCommonsReactiveSecurityConfig; import com.naturalprogrammer.spring.lemonreactive.domain.AbstractMongoUser; import com.naturalprogrammer.spring.lemonreactive.util.LerUtils; @@ -24,11 +27,11 @@ public class LemonReactiveSecurityConfig, ID ext protected LemonReactiveUserDetailsService userDetailsService; private LemonProperties properties; - private ReactiveOAuth2AuthenticationSuccessHandler reactiveOAuth2AuthenticationSuccessHandler; + private ReactiveOAuth2AuthenticationSuccessHandler reactiveOAuth2AuthenticationSuccessHandler; public LemonReactiveSecurityConfig(BlueTokenService blueTokenService, LemonReactiveUserDetailsService userDetailsService, - ReactiveOAuth2AuthenticationSuccessHandler reactiveOAuth2AuthenticationSuccessHandler, + ReactiveOAuth2AuthenticationSuccessHandler reactiveOAuth2AuthenticationSuccessHandler, LemonProperties properties) { super(blueTokenService); @@ -68,7 +71,7 @@ protected void oauth2Login(ServerHttpSecurity http) { http.oauth2Login() .authorizedClientRepository(new ReactiveCookieServerOAuth2AuthorizedClientRepository(properties)) .authenticationSuccessHandler(reactiveOAuth2AuthenticationSuccessHandler) - .authenticationManager(authenticationManager); + .authenticationFailureHandler(this::onAuthenticationFailure); } @Override @@ -84,4 +87,13 @@ protected Mono fetchUserDto(JWTClaimsSet claims) { }) .map(AbstractMongoUser::toUserDto); } + + protected Mono onAuthenticationFailure(WebFilterExchange webFilterExchange, AuthenticationException exception) { + + ReactiveCookieServerOAuth2AuthorizedClientRepository.deleteCookies(webFilterExchange.getExchange(), + LecUtils.AUTHORIZATION_REQUEST_COOKIE_NAME, + LecUtils.LEMON_REDIRECT_URI_COOKIE_PARAM_NAME); + + return Mono.error(exception); + } } diff --git a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/security/ReactiveCookieServerOAuth2AuthorizedClientRepository.java b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/security/ReactiveCookieServerOAuth2AuthorizedClientRepository.java index 9c3ba0e7..f2d35824 100644 --- a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/security/ReactiveCookieServerOAuth2AuthorizedClientRepository.java +++ b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/security/ReactiveCookieServerOAuth2AuthorizedClientRepository.java @@ -15,15 +15,12 @@ import com.naturalprogrammer.spring.lemon.commons.LemonProperties; import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; -import com.naturalprogrammer.spring.lemonreactive.util.LerUtils; +import com.naturalprogrammer.spring.lemon.commonsreactive.util.LecrUtils; import reactor.core.publisher.Mono; public class ReactiveCookieServerOAuth2AuthorizedClientRepository implements ServerOAuth2AuthorizedClientRepository { - public static final String AUTHORIZATION_REQUEST_COOKIE_NAME = "lemon_oauth2_authorization_request"; - public static final String LEMON_REDIRECT_URI_COOKIE_PARAM_NAME = "lemon_redirect_uri"; - private int cookieExpirySecs; public ReactiveCookieServerOAuth2AuthorizedClientRepository(LemonProperties properties) { @@ -35,7 +32,7 @@ public ReactiveCookieServerOAuth2AuthorizedClientRepository(LemonProperties prop public Mono loadAuthorizedClient(String clientRegistrationId, Authentication principal, ServerWebExchange exchange) { - return LerUtils.fetchCookie(exchange, AUTHORIZATION_REQUEST_COOKIE_NAME) + return LecrUtils.fetchCookie(exchange, LecUtils.AUTHORIZATION_REQUEST_COOKIE_NAME) .map(this::deserialize) .orElse(Mono.empty()); } @@ -49,12 +46,12 @@ public Mono saveAuthorizedClient(OAuth2AuthorizedClient authorizedClient, Assert.notNull(exchange, "exchange cannot be null"); if (authorizedClient == null) { - deleteCookies(exchange, AUTHORIZATION_REQUEST_COOKIE_NAME, LEMON_REDIRECT_URI_COOKIE_PARAM_NAME); + deleteCookies(exchange, LecUtils.AUTHORIZATION_REQUEST_COOKIE_NAME, LecUtils.LEMON_REDIRECT_URI_COOKIE_PARAM_NAME); return Mono.empty(); } ResponseCookie cookie = ResponseCookie - .from(AUTHORIZATION_REQUEST_COOKIE_NAME, LecUtils.serialize(authorizedClient)) + .from(LecUtils.AUTHORIZATION_REQUEST_COOKIE_NAME, LecUtils.serialize(authorizedClient)) .path("/") .httpOnly(true) .maxAge(cookieExpirySecs) @@ -63,12 +60,12 @@ public Mono saveAuthorizedClient(OAuth2AuthorizedClient authorizedClient, response.addCookie(cookie); String lemonRedirectUri = exchange.getRequest() - .getQueryParams().getFirst(LEMON_REDIRECT_URI_COOKIE_PARAM_NAME); + .getQueryParams().getFirst(LecUtils.LEMON_REDIRECT_URI_COOKIE_PARAM_NAME); if (StringUtils.isNotBlank(lemonRedirectUri)) { cookie = ResponseCookie - .from(LEMON_REDIRECT_URI_COOKIE_PARAM_NAME, lemonRedirectUri) + .from(LecUtils.LEMON_REDIRECT_URI_COOKIE_PARAM_NAME, lemonRedirectUri) .path("/") .httpOnly(true) .maxAge(cookieExpirySecs) @@ -84,11 +81,11 @@ public Mono saveAuthorizedClient(OAuth2AuthorizedClient authorizedClient, public Mono removeAuthorizedClient(String clientRegistrationId, Authentication principal, ServerWebExchange exchange) { - deleteCookies(exchange, AUTHORIZATION_REQUEST_COOKIE_NAME); + deleteCookies(exchange, LecUtils.AUTHORIZATION_REQUEST_COOKIE_NAME); return Mono.empty(); } - private void deleteCookies(ServerWebExchange exchange, String ...cookiesToDelete) { + public static void deleteCookies(ServerWebExchange exchange, String ...cookiesToDelete) { MultiValueMap cookies = exchange.getRequest().getCookies(); MultiValueMap responseCookies = exchange.getResponse().getCookies(); diff --git a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/security/ReactiveOAuth2AuthenticationSuccessHandler.java b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/security/ReactiveOAuth2AuthenticationSuccessHandler.java index caf8db58..44151b9a 100644 --- a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/security/ReactiveOAuth2AuthenticationSuccessHandler.java +++ b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/security/ReactiveOAuth2AuthenticationSuccessHandler.java @@ -2,13 +2,17 @@ import java.io.Serializable; import java.net.URI; -import java.util.Optional; +import java.util.Map; +import org.apache.commons.lang3.exception.ExceptionUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.springframework.http.HttpCookie; import org.springframework.security.core.Authentication; import org.springframework.security.core.context.ReactiveSecurityContextHolder; -import org.springframework.security.oauth2.client.authentication.OAuth2LoginAuthenticationToken; +import org.springframework.security.core.context.SecurityContext; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken; import org.springframework.security.oauth2.core.user.OAuth2User; import org.springframework.security.web.server.DefaultServerRedirectStrategy; import org.springframework.security.web.server.ServerRedirectStrategy; @@ -20,7 +24,12 @@ import com.naturalprogrammer.spring.lemon.commons.security.BlueTokenService; import com.naturalprogrammer.spring.lemon.commons.security.LemonPrincipal; import com.naturalprogrammer.spring.lemon.commons.security.UserDto; +import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; import com.naturalprogrammer.spring.lemon.commonsreactive.util.LecrUtils; +import com.naturalprogrammer.spring.lemon.exceptions.util.LexUtils; +import com.naturalprogrammer.spring.lemonreactive.LemonReactiveService; +import com.naturalprogrammer.spring.lemonreactive.domain.AbstractMongoUser; +import com.naturalprogrammer.spring.lemonreactive.domain.AbstractMongoUserRepository; import lombok.AllArgsConstructor; import reactor.core.publisher.Mono; @@ -32,13 +41,17 @@ * @author Sanjay Patel */ @AllArgsConstructor -public class ReactiveOAuth2AuthenticationSuccessHandler +public class ReactiveOAuth2AuthenticationSuccessHandler, ID extends Serializable> implements ServerAuthenticationSuccessHandler { private static final Log log = LogFactory.getLog(ReactiveOAuth2AuthenticationSuccessHandler.class); private static final ServerRedirectStrategy redirectStrategy = new DefaultServerRedirectStrategy(); private BlueTokenService blueTokenService; + private AbstractMongoUserRepository userRepository; + private LemonReactiveUserDetailsService userDetailsService; + private LemonReactiveService lemonService; + private PasswordEncoder passwordEncoder; private LemonProperties properties; @Override @@ -48,23 +61,63 @@ public Mono onAuthenticationSuccess(WebFilterExchange webFilterExchange, ServerWebExchange exchange = webFilterExchange.getExchange(); return ReactiveSecurityContextHolder.getContext() - .cast(OAuth2LoginAuthenticationToken.class) - .map(this::toLemonPrincipal) + .map(SecurityContext::getAuthentication) + .cast(OAuth2AuthenticationToken.class) + .flatMap(token -> buildPrincipal(token.getPrincipal(), token.getAuthorizedClientRegistrationId())) .map(LemonPrincipal::currentUser) .map(this::getAuthToken) + .map(authToken -> getTargetUrl(exchange, authToken)) .map(URI::create) .flatMap(location -> redirectStrategy.sendRedirect(exchange, location)); } - private LemonPrincipal toLemonPrincipal(OAuth2LoginAuthenticationToken token) { + /** + * Builds the security principal from the given userReqest. + * Registers the user if not already registered + */ + public Mono buildPrincipal(OAuth2User oath2User, String registrationId) { - String registrationId = token.getClientRegistration().getRegistrationId(); - OAuth2User principal = token.getPrincipal(); + Map attributes = oath2User.getAttributes(); + String email = lemonService.getOAuth2Email(registrationId, attributes); + LexUtils.validate(email != null, "com.naturalprogrammer.spring.oauth2EmailNeeded", registrationId).go(); - return new LemonPrincipal(); - + boolean emailVerified = lemonService.getOAuth2AccountVerified(registrationId, attributes); + LexUtils.validate(emailVerified, "com.naturalprogrammer.spring.oauth2EmailNotVerified", registrationId).go(); + + return userDetailsService.findUserByUsername(email) + .switchIfEmpty(newUser(email, registrationId, attributes)) + .map(U::toUserDto) + .map(userDto -> { + + LemonPrincipal principal = new LemonPrincipal(userDto); + principal.setAttributes(attributes); + principal.setName(oath2User.getName()); + + return principal; + }); } + private Mono newUser(String email, String registrationId, Map attributes) { + + // register a new user + U newUser = lemonService.newUser(); + newUser.setEmail(email); + newUser.setPassword(passwordEncoder.encode(LecUtils.uid())); + + lemonService.fillAdditionalFields(registrationId, newUser, attributes); + return userRepository.insert(newUser).doOnSuccess(user -> { + try { + + lemonService.mailForgotPasswordLink(newUser); + + } catch (Throwable e) { + + // In case of exception, just log the error and keep silent + log.error(ExceptionUtils.getStackTrace(e)); + } + }); + } + private String getAuthToken(UserDto user) { String shortLivedAuthToken = blueTokenService.createToken( @@ -74,4 +127,18 @@ private String getAuthToken(UserDto user) { return shortLivedAuthToken; } + + private String getTargetUrl(ServerWebExchange exchange, String shortLivedAuthToken) { + + String targetUrl = LecrUtils.fetchCookie(exchange, + LecUtils.LEMON_REDIRECT_URI_COOKIE_PARAM_NAME) + .map(HttpCookie::getValue) + .orElse(properties.getOauth2AuthenticationSuccessUrl()); + + ReactiveCookieServerOAuth2AuthorizedClientRepository.deleteCookies(exchange, + LecUtils.AUTHORIZATION_REQUEST_COOKIE_NAME, + LecUtils.LEMON_REDIRECT_URI_COOKIE_PARAM_NAME); + + return targetUrl + shortLivedAuthToken; + } } diff --git a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/util/LerUtils.java b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/util/LerUtils.java index b1752551..02b705e0 100644 --- a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/util/LerUtils.java +++ b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/util/LerUtils.java @@ -1,12 +1,9 @@ package com.naturalprogrammer.spring.lemonreactive.util; import java.io.Serializable; -import java.util.Optional; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import org.springframework.http.HttpCookie; -import org.springframework.web.server.ServerWebExchange; import com.naturalprogrammer.spring.lemon.commons.security.LemonTokenService; import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; @@ -37,8 +34,4 @@ void ensureCredentialsUpToDate(JWTClaimsSet claims, U user) { LecUtils.ensureCredentials(issueTime >= user.getCredentialsUpdatedMillis(), "com.naturalprogrammer.spring.obsoleteToken"); } - - public static Optional fetchCookie(ServerWebExchange exchange, String cookieName) { - return Optional.ofNullable(exchange.getRequest().getCookies().getFirst(cookieName)); - } } From c9651d538a9ac352be62a094df3249892d711579 Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Thu, 26 Sep 2019 07:16:55 +0530 Subject: [PATCH 097/116] Some OAuthLogin configuration improvements --- .../LemonCommonsReactiveSecurityConfig.java | 24 ++++--------------- .../security/LemonJpaSecurityConfig.java | 1 + .../security/LemonReactiveSecurityConfig.java | 9 ++++--- 3 files changed, 12 insertions(+), 22 deletions(-) diff --git a/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/security/LemonCommonsReactiveSecurityConfig.java b/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/security/LemonCommonsReactiveSecurityConfig.java index 6d9cd7dd..9580a012 100644 --- a/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/security/LemonCommonsReactiveSecurityConfig.java +++ b/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/security/LemonCommonsReactiveSecurityConfig.java @@ -8,8 +8,10 @@ import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.config.web.server.SecurityWebFiltersOrder; import org.springframework.security.config.web.server.ServerHttpSecurity; +import org.springframework.security.core.AuthenticationException; import org.springframework.security.web.server.SecurityWebFilterChain; import org.springframework.security.web.server.ServerAuthenticationEntryPoint; +import org.springframework.security.web.server.WebFilterExchange; import org.springframework.security.web.server.authentication.AuthenticationWebFilter; import org.springframework.security.web.server.authentication.ServerAuthenticationConverter; import org.springframework.security.web.server.authentication.ServerAuthenticationFailureHandler; @@ -44,8 +46,8 @@ public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) return http .securityContextRepository(NoOpServerSecurityContextRepository.getInstance()) .exceptionHandling() - .accessDeniedHandler(accessDeniedHandler()) - .authenticationEntryPoint(authenticationEntryPoint()) + .accessDeniedHandler((exchange, exception) -> Mono.error(exception)) + .authenticationEntryPoint((exchange, exception) -> Mono.error(exception)) .and() .cors() .and() @@ -86,7 +88,7 @@ protected AuthenticationWebFilter tokenAuthenticationFilter() { AuthenticationWebFilter filter = new AuthenticationWebFilter(tokenAuthenticationManager()); filter.setServerAuthenticationConverter(tokenAuthenticationConverter()); - filter.setAuthenticationFailureHandler(authenticationFailureHandler()); + filter.setAuthenticationFailureHandler((exchange, exception) -> Mono.error(exception)); return filter; } @@ -136,20 +138,4 @@ protected ServerAuthenticationConverter tokenAuthenticationConverter() { return Mono.just(new UsernamePasswordAuthenticationToken(null, authorization.substring(LecUtils.TOKEN_PREFIX_LENGTH))); }; } - - protected ServerAuthenticationFailureHandler authenticationFailureHandler() { - - return (webFilterExchange, exception) -> Mono.error(exception); - } - - protected ServerAccessDeniedHandler accessDeniedHandler() { - - return (exchange, exception) -> Mono.error(exception); - } - - protected ServerAuthenticationEntryPoint authenticationEntryPoint() { - - return (exchange, exception) -> Mono.error(exception); - } - } diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonJpaSecurityConfig.java b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonJpaSecurityConfig.java index 39534755..afaead2e 100644 --- a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonJpaSecurityConfig.java +++ b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonJpaSecurityConfig.java @@ -4,6 +4,7 @@ import org.apache.commons.logging.LogFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.http.SessionCreationPolicy; import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; diff --git a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/security/LemonReactiveSecurityConfig.java b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/security/LemonReactiveSecurityConfig.java index 517e96ef..a1d6dc12 100644 --- a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/security/LemonReactiveSecurityConfig.java +++ b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/security/LemonReactiveSecurityConfig.java @@ -9,6 +9,7 @@ import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.security.web.server.WebFilterExchange; import org.springframework.security.web.server.authentication.WebFilterChainServerAuthenticationSuccessHandler; +import org.springframework.security.web.server.context.NoOpServerSecurityContextRepository; import com.naturalprogrammer.spring.lemon.commons.LemonProperties; import com.naturalprogrammer.spring.lemon.commons.security.BlueTokenService; @@ -49,8 +50,9 @@ public LemonReactiveSecurityConfig(BlueTokenService blueTokenService, protected void formLogin(ServerHttpSecurity http) { http.formLogin() + .securityContextRepository(NoOpServerSecurityContextRepository.getInstance()) .loginPage(loginPage()) // Should be "/login" by default, but not providing that overwrites our AuthenticationFailureHandler, because this is called later - .authenticationFailureHandler(authenticationFailureHandler()) + .authenticationFailureHandler((exchange, exception) -> Mono.error(exception)) .authenticationSuccessHandler(new WebFilterChainServerAuthenticationSuccessHandler()); } @@ -69,9 +71,10 @@ protected String loginPage() { protected void oauth2Login(ServerHttpSecurity http) { http.oauth2Login() + .securityContextRepository(NoOpServerSecurityContextRepository.getInstance()) .authorizedClientRepository(new ReactiveCookieServerOAuth2AuthorizedClientRepository(properties)) .authenticationSuccessHandler(reactiveOAuth2AuthenticationSuccessHandler) - .authenticationFailureHandler(this::onAuthenticationFailure); + .authenticationFailureHandler(this::onOauth2AuthenticationFailure); } @Override @@ -88,7 +91,7 @@ protected Mono fetchUserDto(JWTClaimsSet claims) { .map(AbstractMongoUser::toUserDto); } - protected Mono onAuthenticationFailure(WebFilterExchange webFilterExchange, AuthenticationException exception) { + protected Mono onOauth2AuthenticationFailure(WebFilterExchange webFilterExchange, AuthenticationException exception) { ReactiveCookieServerOAuth2AuthorizedClientRepository.deleteCookies(webFilterExchange.getExchange(), LecUtils.AUTHORIZATION_REQUEST_COOKIE_NAME, From 256029794425610d01bc780d3b4245f2c15c61b6 Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Thu, 26 Sep 2019 08:34:46 +0530 Subject: [PATCH 098/116] Facebook OAuth related changes --- .../src/main/resources/config/application-dev.yml | 6 +++--- .../src/main/resources/config/application-dev.yml | 6 +++--- .../spring/lemon/commons/AbstractLemonService.java | 5 +++++ ...ookieServerOAuth2AuthorizedClientRepository.java | 13 +++++++++++++ 4 files changed, 24 insertions(+), 6 deletions(-) diff --git a/lemon-demo-jpa/src/main/resources/config/application-dev.yml b/lemon-demo-jpa/src/main/resources/config/application-dev.yml index b17b46ca..40d6a2a6 100644 --- a/lemon-demo-jpa/src/main/resources/config/application-dev.yml +++ b/lemon-demo-jpa/src/main/resources/config/application-dev.yml @@ -16,14 +16,14 @@ spring: client: provider: facebook: - user-info-uri: https://graph.facebook.com/me?fields=email,name,verified + user-info-uri: https://graph.facebook.com/me?fields=email,name registration: google: client-id: 1011974249454-6gq0hr01gqh3cndoqnss5r69tkk2nd84.apps.googleusercontent.com client-secret: saDA6Cj60wipncFM-hzBD-C6 facebook: - client-id: 1234020186718741 - client-secret: 0c0abaf685a83e879e8e48b1167c96ab + client-id: 548349525905412 + client-secret: 15a20c560c4c780dabdc0e637c02087a logging: level: diff --git a/lemon-demo-reactive/src/main/resources/config/application-dev.yml b/lemon-demo-reactive/src/main/resources/config/application-dev.yml index db1cf09b..78ff07d2 100644 --- a/lemon-demo-reactive/src/main/resources/config/application-dev.yml +++ b/lemon-demo-reactive/src/main/resources/config/application-dev.yml @@ -10,14 +10,14 @@ spring: client: provider: facebook: - user-info-uri: https://graph.facebook.com/me?fields=email,name,verified + user-info-uri: https://graph.facebook.com/me?fields=email,name registration: google: client-id: 1011974249454-6gq0hr01gqh3cndoqnss5r69tkk2nd84.apps.googleusercontent.com client-secret: saDA6Cj60wipncFM-hzBD-C6 facebook: - client-id: 1234020186718741 - client-secret: 0c0abaf685a83e879e8e48b1167c96ab + client-id: 548349525905412 + client-secret: 15a20c560c4c780dabdc0e637c02087a logging: level: diff --git a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/AbstractLemonService.java b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/AbstractLemonService.java index d55be212..fb2149ab 100644 --- a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/AbstractLemonService.java +++ b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/AbstractLemonService.java @@ -202,6 +202,11 @@ public void fillAdditionalFields(String clientId, U user, Map at */ public boolean getOAuth2AccountVerified(String registrationId, Map attributes) { + // Facebook no more returns verified + // https://developers.facebook.com/docs/graph-api/reference/user + if ("facebook".equals(registrationId)) + return true; + Object verified = attributes.get(StandardClaimNames.EMAIL_VERIFIED); if (verified == null) verified = attributes.get("verified"); diff --git a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/security/ReactiveCookieServerOAuth2AuthorizedClientRepository.java b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/security/ReactiveCookieServerOAuth2AuthorizedClientRepository.java index f2d35824..b0f5c710 100644 --- a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/security/ReactiveCookieServerOAuth2AuthorizedClientRepository.java +++ b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/security/ReactiveCookieServerOAuth2AuthorizedClientRepository.java @@ -3,6 +3,8 @@ import java.util.Collections; import org.apache.commons.lang3.StringUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; import org.springframework.http.HttpCookie; import org.springframework.http.ResponseCookie; import org.springframework.http.server.reactive.ServerHttpResponse; @@ -21,6 +23,8 @@ public class ReactiveCookieServerOAuth2AuthorizedClientRepository implements ServerOAuth2AuthorizedClientRepository { + private static final Log log = LogFactory.getLog(ReactiveCookieServerOAuth2AuthorizedClientRepository.class); + private int cookieExpirySecs; public ReactiveCookieServerOAuth2AuthorizedClientRepository(LemonProperties properties) { @@ -32,6 +36,9 @@ public ReactiveCookieServerOAuth2AuthorizedClientRepository(LemonProperties prop public Mono loadAuthorizedClient(String clientRegistrationId, Authentication principal, ServerWebExchange exchange) { + log.debug("Loading authorized client for clientRegistrationId " + clientRegistrationId + + ", principal " + principal + ", and exchange " + exchange); + return LecrUtils.fetchCookie(exchange, LecUtils.AUTHORIZATION_REQUEST_COOKIE_NAME) .map(this::deserialize) .orElse(Mono.empty()); @@ -41,6 +48,9 @@ public Mono loadAuthorizedClient(String clientRegistrati public Mono saveAuthorizedClient(OAuth2AuthorizedClient authorizedClient, Authentication principal, ServerWebExchange exchange) { + log.debug("Saving authorized client " + authorizedClient + + " for principal " + principal + ", and exchange " + exchange); + ServerHttpResponse response = exchange.getResponse(); Assert.notNull(exchange, "exchange cannot be null"); @@ -81,6 +91,9 @@ public Mono saveAuthorizedClient(OAuth2AuthorizedClient authorizedClient, public Mono removeAuthorizedClient(String clientRegistrationId, Authentication principal, ServerWebExchange exchange) { + log.debug("Deleting authorized client for clientRegistrationId " + clientRegistrationId + + ", principal " + principal + ", and exchange " + exchange); + deleteCookies(exchange, LecUtils.AUTHORIZATION_REQUEST_COOKIE_NAME); return Mono.empty(); } From 4e7632be953c5b260cc745a7605f65092222e974 Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Sat, 19 Oct 2019 07:32:12 +0530 Subject: [PATCH 099/116] Upgraded to Spring Boot 2.2.0 --- .../spring/lemondemo/services/MyService.java | 25 +++++++++++++++++++ pom.xml | 2 +- 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/lemon-demo-reactive/src/main/java/com/naturalprogrammer/spring/lemondemo/services/MyService.java b/lemon-demo-reactive/src/main/java/com/naturalprogrammer/spring/lemondemo/services/MyService.java index 9f06938c..8b100a2a 100644 --- a/lemon-demo-reactive/src/main/java/com/naturalprogrammer/spring/lemondemo/services/MyService.java +++ b/lemon-demo-reactive/src/main/java/com/naturalprogrammer/spring/lemondemo/services/MyService.java @@ -1,6 +1,9 @@ package com.naturalprogrammer.spring.lemondemo.services; +import java.util.Map; + import org.bson.types.ObjectId; +import org.springframework.security.oauth2.core.oidc.StandardClaimNames; import org.springframework.stereotype.Service; import com.naturalprogrammer.spring.lemon.commons.security.UserDto; @@ -32,6 +35,28 @@ protected void updateUserFields(User user, User updatedUser, UserDto currentUser user.setName(updatedUser.getName()); } + @Override + public void fillAdditionalFields(String registrationId, User user, Map attributes) { + + String nameKey; + + switch (registrationId) { + + case "facebook": + nameKey = StandardClaimNames.NAME; + break; + + case "google": + nameKey = StandardClaimNames.NAME; + break; + + default: + throw new UnsupportedOperationException("Fetching name from " + registrationId + " login not supprrted"); + } + + user.setName((String) attributes.get(nameKey)); + } + @Override protected ObjectId toId(String id) { return new ObjectId(id); diff --git a/pom.xml b/pom.xml index 03425be5..779fe9f4 100644 --- a/pom.xml +++ b/pom.xml @@ -15,7 +15,7 @@ org.springframework.boot spring-boot-starter-parent - 2.2.0.BUILD-SNAPSHOT + 2.2.0.RELEASE From d59b1397649ea6bb41b329b6420c5b9914732c69 Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Fri, 22 May 2020 11:44:02 +0530 Subject: [PATCH 100/116] Spring Boot 2.3.0 Update --- lemon-demo-jpa/pom.xml | 2 +- .../spring/lemondemo/MySecurityConfig.java | 3 +- .../lemondemo/controllers/MyController.java | 5 +- .../spring/lemondemo/entities/User.java | 18 ++--- .../spring/lemondemo/services/MyService.java | 9 +-- .../spring/lemondemo/AbstractMvcTests.java | 21 +++--- .../spring/lemondemo/BasicMvcTests.java | 11 +-- .../spring/lemondemo/ChangeEmailMvcTests.java | 15 ++-- .../lemondemo/ChangePasswordMvcTests.java | 15 ++-- .../lemondemo/FetchNewTokenMvcTests.java | 13 ++-- .../spring/lemondemo/FetchUserMvcTests.java | 10 +-- .../lemondemo/ForgotPasswordMvcTests.java | 6 +- .../spring/lemondemo/LoginMvcTests.java | 17 ++--- .../lemondemo/RequestEmailChangeMvcTests.java | 17 ++--- .../ResendVerificationMailMvcTests.java | 6 +- .../lemondemo/ResetPasswordMvcTests.java | 17 ++--- .../spring/lemondemo/SignupMvcTests.java | 21 ++---- .../spring/lemondemo/UpdateUserMvcTests.java | 21 +++--- .../lemondemo/VerificationMvcTests.java | 17 ++--- lemon-demo-reactive/pom.xml | 2 +- .../lemondemo/controllers/MyController.java | 14 ++-- .../spring/lemondemo/domain/User.java | 17 ++--- .../repositories/UserRepository.java | 2 +- .../spring/lemondemo/services/MyService.java | 9 +-- .../spring/lemondemo/AbstractTests.java | 21 +++--- .../spring/lemondemo/BasicTests.java | 9 +-- .../spring/lemondemo/ChangeEmailTests.java | 33 ++++----- .../spring/lemondemo/ChangePasswordTests.java | 22 ++---- .../spring/lemondemo/FetchNewTokenTests.java | 16 ++-- .../spring/lemondemo/FetchUserTests.java | 13 +--- .../spring/lemondemo/ForgotPasswordTests.java | 8 +- .../spring/lemondemo/LoginTests.java | 26 +++---- .../spring/lemondemo/MyTestUtils.java | 31 ++++---- .../lemondemo/RequestEmailChangeTests.java | 36 ++++----- .../ResendVerificationMailTests.java | 18 ++--- .../spring/lemondemo/ResetPasswordTests.java | 16 ++-- .../spring/lemondemo/SignupTests.java | 45 +++++------- .../spring/lemondemo/TestConfiguration.java | 14 ++++ .../spring/lemondemo/UpdateUserTests.java | 29 +++----- .../spring/lemondemo/VerificationTests.java | 19 ++--- .../lemondemo/dto/TestErrorResponse.java | 4 +- .../spring/lemondemo/dto/TestUserDto.java | 10 +-- pom.xml | 4 +- spring-lemon-commons-jpa/pom.xml | 2 +- .../spring/lemon/commonsjpa/LecjUtils.java | 8 +- .../LemonCommonsJpaAutoConfiguration.java | 3 +- .../spring/lemon/commonsjpa/LemonEntity.java | 25 +++---- spring-lemon-commons-mongo/pom.xml | 2 +- .../lemon/commonsmongo/AbstractDocument.java | 17 ++--- .../spring/lemon/commonsmongo/LecmUtils.java | 7 +- .../LemonCommonsMongoAutoConfiguration.java | 3 +- spring-lemon-commons-reactive/pom.xml | 2 +- ...LemonCommonsReactiveAutoConfiguration.java | 29 ++++---- .../LemonReactiveErrorAttributes.java | 12 +-- .../handlers/VersionExceptionHandler.java | 5 +- .../LemonCommonsReactiveSecurityConfig.java | 21 ++---- .../LemonCorsConfigurationSource.java | 7 +- .../security/LemonReactiveAuditorAware.java | 12 +-- .../lemon/commonsreactive/util/LecrUtils.java | 25 +++---- spring-lemon-commons-web/pom.xml | 2 +- .../LemonCommonsWebAutoConfiguration.java | 29 ++++---- ...faultExceptionHandlerControllerAdvice.java | 5 +- .../exceptions/LemonErrorAttributes.java | 12 +-- .../exceptions/LemonErrorController.java | 15 ++-- ...onCommonsWebTokenAuthenticationFilter.java | 27 +++---- .../LemonCorsConfigurationSource.java | 10 +-- .../security/LemonWebAuditorAware.java | 9 +-- .../security/LemonWebSecurityConfig.java | 5 +- .../lemon/commonsweb/util/LecwUtils.java | 12 ++- spring-lemon-commons/pom.xml | 2 +- .../lemon/commons/AbstractLemonService.java | 29 ++++---- .../LemonCommonsAutoConfiguration.java | 27 +++---- .../spring/lemon/commons/LemonProperties.java | 10 +-- .../commons/domain/AbstractAuditorAware.java | 7 +- .../commons/domain/ChangePasswordForm.java | 1 - .../commons/domain/ResetPasswordForm.java | 5 +- .../AccessDeniedExceptionHandler.java | 3 +- .../BadCredentialsExceptionHandler.java | 3 +- .../handlers/JsonParseExceptionHandler.java | 5 +- .../handlers/JsonPatchExceptionHandler.java | 5 +- .../JsonProcessingExceptionHandler.java | 5 +- .../UsernameNotFoundExceptionHandler.java | 3 +- .../lemon/commons/mail/SmtpMailSender.java | 6 +- .../commons/security/AbstractJwtService.java | 13 ++-- .../security/LemonGrantedAuthority.java | 3 +- .../commons/security/LemonJweService.java | 21 ++---- .../commons/security/LemonJwsService.java | 18 ++--- .../security/LemonPermissionEvaluator.java | 5 +- .../commons/security/LemonPrincipal.java | 22 +++--- .../commons/security/LemonTokenService.java | 4 +- .../lemon/commons/security/UserDto.java | 11 ++- .../commons/security/UserEditPermission.java | 4 +- .../spring/lemon/commons/util/LecUtils.java | 33 ++++----- .../spring/lemon/commons/util/UserUtils.java | 3 +- .../lemon/commons/validation/Captcha.java | 3 +- .../commons/validation/CaptchaValidator.java | 19 ++--- .../lemon/commons/validation/Password.java | 7 +- .../commons/validation/RetypePassword.java | 3 +- .../validation/RetypePasswordValidator.java | 7 +- .../security/LemonJwtServiceTests.java | 7 +- spring-lemon-exceptions/pom.xml | 2 +- .../lemon/exceptions/ErrorResponse.java | 4 +- .../exceptions/ErrorResponseComposer.java | 21 +++--- .../LemonExceptionsAutoConfiguration.java | 7 +- .../lemon/exceptions/LemonFieldError.java | 19 +++-- .../lemon/exceptions/MultiErrorException.java | 15 ++-- .../lemon/exceptions/VersionException.java | 3 +- .../handlers/AbstractExceptionHandler.java | 9 +-- .../AbstractValidationExceptionHandler.java | 3 +- .../ConstraintViolationExceptionHandler.java | 8 +- .../handlers/MultiErrorExceptionHandler.java | 7 +- .../WebExchangeBindExceptionHandler.java | 5 +- .../lemon/exceptions/util/LexUtils.java | 12 ++- spring-lemon-jpa/pom.xml | 2 +- .../spring/lemon/LemonAutoConfiguration.java | 35 ++++----- .../spring/lemon/LemonController.java | 36 ++++----- .../spring/lemon/LemonService.java | 73 +++++++------------ .../spring/lemon/domain/AbstractUser.java | 18 ++--- .../lemon/domain/AbstractUserRepository.java | 6 +- ...eOAuth2AuthorizationRequestRepository.java | 13 ++-- .../LemonAuthenticationSuccessHandler.java | 20 +++-- .../security/LemonJpaSecurityConfig.java | 8 +- .../LemonJpaTokenAuthenticationFilter.java | 11 ++- .../security/LemonOAuth2UserService.java | 30 ++++---- .../lemon/security/LemonOidcUserService.java | 6 +- .../security/LemonUserDetailsService.java | 16 ++-- .../OAuth2AuthenticationFailureHandler.java | 10 +-- .../OAuth2AuthenticationSuccessHandler.java | 16 ++-- .../spring/lemon/util/LemonUtils.java | 13 ++-- .../spring/lemon/validation/UniqueEmail.java | 7 +- .../validation/UniqueEmailValidator.java | 7 +- spring-lemon-reactive/pom.xml | 2 +- .../LemonReactiveAutoConfiguration.java | 25 +++---- .../LemonReactiveController.java | 42 ++++------- .../lemonreactive/LemonReactiveService.java | 61 +++++++--------- .../domain/AbstractMongoUser.java | 16 ++-- .../domain/AbstractMongoUserRepository.java | 5 +- .../spring/lemonreactive/forms/EmailForm.java | 1 - .../security/LemonReactiveSecurityConfig.java | 22 +++--- .../LemonReactiveUserDetailsService.java | 14 ++-- ...erverOAuth2AuthorizedClientRepository.java | 14 ++-- ...iveOAuth2AuthenticationSuccessHandler.java | 38 +++++----- .../spring/lemonreactive/util/LerUtils.java | 9 +-- .../lemonreactive/validation/UniqueEmail.java | 7 +- .../validation/UniqueEmailValidator.java | 35 ++++++--- 145 files changed, 844 insertions(+), 1151 deletions(-) create mode 100644 lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/TestConfiguration.java diff --git a/lemon-demo-jpa/pom.xml b/lemon-demo-jpa/pom.xml index 83bf617e..04512799 100644 --- a/lemon-demo-jpa/pom.xml +++ b/lemon-demo-jpa/pom.xml @@ -14,7 +14,7 @@ com.naturalprogrammer spring-lemon - 1.0.0.RC3 + 1.0.0.RC4 diff --git a/lemon-demo-jpa/src/main/java/com/naturalprogrammer/spring/lemondemo/MySecurityConfig.java b/lemon-demo-jpa/src/main/java/com/naturalprogrammer/spring/lemondemo/MySecurityConfig.java index e9621817..e7627186 100644 --- a/lemon-demo-jpa/src/main/java/com/naturalprogrammer/spring/lemondemo/MySecurityConfig.java +++ b/lemon-demo-jpa/src/main/java/com/naturalprogrammer/spring/lemondemo/MySecurityConfig.java @@ -1,12 +1,11 @@ package com.naturalprogrammer.spring.lemondemo; +import com.naturalprogrammer.spring.lemon.security.LemonJpaSecurityConfig; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.stereotype.Component; -import com.naturalprogrammer.spring.lemon.security.LemonJpaSecurityConfig; - @Component public class MySecurityConfig extends LemonJpaSecurityConfig { diff --git a/lemon-demo-jpa/src/main/java/com/naturalprogrammer/spring/lemondemo/controllers/MyController.java b/lemon-demo-jpa/src/main/java/com/naturalprogrammer/spring/lemondemo/controllers/MyController.java index 09f1dfe2..4f312eaf 100644 --- a/lemon-demo-jpa/src/main/java/com/naturalprogrammer/spring/lemondemo/controllers/MyController.java +++ b/lemon-demo-jpa/src/main/java/com/naturalprogrammer/spring/lemondemo/controllers/MyController.java @@ -1,10 +1,9 @@ package com.naturalprogrammer.spring.lemondemo.controllers; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - import com.naturalprogrammer.spring.lemon.LemonController; import com.naturalprogrammer.spring.lemondemo.entities.User; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping(MyController.BASE_URI) diff --git a/lemon-demo-jpa/src/main/java/com/naturalprogrammer/spring/lemondemo/entities/User.java b/lemon-demo-jpa/src/main/java/com/naturalprogrammer/spring/lemondemo/entities/User.java index b4b380d2..66fa23cf 100644 --- a/lemon-demo-jpa/src/main/java/com/naturalprogrammer/spring/lemondemo/entities/User.java +++ b/lemon-demo-jpa/src/main/java/com/naturalprogrammer/spring/lemondemo/entities/User.java @@ -1,22 +1,20 @@ package com.naturalprogrammer.spring.lemondemo.entities; -import java.io.Serializable; - -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.Table; -import javax.validation.constraints.NotBlank; -import javax.validation.constraints.Size; - import com.fasterxml.jackson.annotation.JsonView; import com.naturalprogrammer.spring.lemon.commons.util.UserUtils; import com.naturalprogrammer.spring.lemon.domain.AbstractUser; - import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; import lombok.ToString; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Table; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.Size; +import java.io.Serializable; + @Entity @Table(name="usr") @Getter @Setter @NoArgsConstructor @@ -43,7 +41,7 @@ public User(String email, String password, String name) { @JsonView(UserUtils.SignupInput.class) @NotBlank(message = "{blank.name}", groups = {UserUtils.SignUpValidation.class, UserUtils.UpdateValidation.class}) @Size(min=NAME_MIN, max=NAME_MAX, groups = {UserUtils.SignUpValidation.class, UserUtils.UpdateValidation.class}) - @Column(nullable = false, length = NAME_MAX) + @Column(nullable = false, length = NAME_MAX) // Note: don't use JPA annotations on getter: https://github.com/naturalprogrammer/spring-lemon/issues/9 private String name; @Override diff --git a/lemon-demo-jpa/src/main/java/com/naturalprogrammer/spring/lemondemo/services/MyService.java b/lemon-demo-jpa/src/main/java/com/naturalprogrammer/spring/lemondemo/services/MyService.java index f8fe2bb8..206cd1c7 100644 --- a/lemon-demo-jpa/src/main/java/com/naturalprogrammer/spring/lemondemo/services/MyService.java +++ b/lemon-demo-jpa/src/main/java/com/naturalprogrammer/spring/lemondemo/services/MyService.java @@ -1,14 +1,13 @@ package com.naturalprogrammer.spring.lemondemo.services; -import java.util.Map; - -import org.springframework.security.oauth2.core.oidc.StandardClaimNames; -import org.springframework.stereotype.Service; - import com.naturalprogrammer.spring.lemon.LemonService; import com.naturalprogrammer.spring.lemon.commons.security.UserDto; import com.naturalprogrammer.spring.lemon.commonsjpa.LecjUtils; import com.naturalprogrammer.spring.lemondemo.entities.User; +import org.springframework.security.oauth2.core.oidc.StandardClaimNames; +import org.springframework.stereotype.Service; + +import java.util.Map; @Service public class MyService extends LemonService { diff --git a/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/AbstractMvcTests.java b/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/AbstractMvcTests.java index f7af9fdd..32d96f66 100644 --- a/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/AbstractMvcTests.java +++ b/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/AbstractMvcTests.java @@ -1,13 +1,8 @@ package com.naturalprogrammer.spring.lemondemo; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; - -import java.util.HashMap; -import java.util.Map; - +import com.naturalprogrammer.spring.lemon.commons.mail.MailSender; +import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; +import com.naturalprogrammer.spring.lemondemo.repositories.UserRepository; import org.junit.Before; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; @@ -23,9 +18,13 @@ import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.MvcResult; -import com.naturalprogrammer.spring.lemon.commons.mail.MailSender; -import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; -import com.naturalprogrammer.spring.lemondemo.repositories.UserRepository; +import java.util.HashMap; +import java.util.Map; + +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @RunWith(SpringRunner.class) @SpringBootTest({ diff --git a/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/BasicMvcTests.java b/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/BasicMvcTests.java index 42c8d86a..182269c6 100644 --- a/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/BasicMvcTests.java +++ b/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/BasicMvcTests.java @@ -1,16 +1,13 @@ package com.naturalprogrammer.spring.lemondemo; -import static org.hamcrest.Matchers.containsString; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; - +import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; import org.junit.Test; import org.springframework.http.HttpHeaders; import org.springframework.test.context.jdbc.Sql; -import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; +import static org.hamcrest.Matchers.containsString; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; @Sql({"/test-data/initialize.sql", "/test-data/finalize.sql", }) public class BasicMvcTests extends AbstractMvcTests { diff --git a/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/ChangeEmailMvcTests.java b/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/ChangeEmailMvcTests.java index f4cba5e0..2556321c 100644 --- a/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/ChangeEmailMvcTests.java +++ b/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/ChangeEmailMvcTests.java @@ -1,11 +1,8 @@ package com.naturalprogrammer.spring.lemondemo; -import static org.hamcrest.Matchers.containsString; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; - +import com.naturalprogrammer.spring.lemon.commons.security.GreenTokenService; +import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; +import com.naturalprogrammer.spring.lemondemo.entities.User; import org.junit.Assert; import org.junit.Before; import org.junit.Test; @@ -13,9 +10,9 @@ import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; -import com.naturalprogrammer.spring.lemon.commons.security.GreenTokenService; -import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; -import com.naturalprogrammer.spring.lemondemo.entities.User; +import static org.hamcrest.Matchers.containsString; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; public class ChangeEmailMvcTests extends AbstractMvcTests { diff --git a/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/ChangePasswordMvcTests.java b/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/ChangePasswordMvcTests.java index 818e4d26..22668e99 100644 --- a/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/ChangePasswordMvcTests.java +++ b/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/ChangePasswordMvcTests.java @@ -1,20 +1,15 @@ package com.naturalprogrammer.spring.lemondemo; -import static org.hamcrest.Matchers.containsString; -import static org.hamcrest.Matchers.hasItems; -import static org.hamcrest.Matchers.hasSize; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; - +import com.naturalprogrammer.spring.lemon.commons.domain.ChangePasswordForm; +import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; import org.junit.Test; import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; import org.springframework.test.context.jdbc.Sql; -import com.naturalprogrammer.spring.lemon.commons.domain.ChangePasswordForm; -import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; +import static org.hamcrest.Matchers.*; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; @Sql({"/test-data/initialize.sql", "/test-data/finalize.sql"}) public class ChangePasswordMvcTests extends AbstractMvcTests { diff --git a/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/FetchNewTokenMvcTests.java b/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/FetchNewTokenMvcTests.java index 862801f7..4aa283a9 100644 --- a/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/FetchNewTokenMvcTests.java +++ b/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/FetchNewTokenMvcTests.java @@ -1,17 +1,16 @@ package com.naturalprogrammer.spring.lemondemo; -import static org.hamcrest.Matchers.containsString; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; - +import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; import org.junit.Test; import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; import org.springframework.test.web.servlet.MvcResult; -import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; +import static org.hamcrest.Matchers.containsString; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; public class FetchNewTokenMvcTests extends AbstractMvcTests { diff --git a/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/FetchUserMvcTests.java b/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/FetchUserMvcTests.java index 259a63ef..6f875792 100644 --- a/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/FetchUserMvcTests.java +++ b/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/FetchUserMvcTests.java @@ -1,15 +1,15 @@ package com.naturalprogrammer.spring.lemondemo; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; - import org.junit.Test; import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; import org.springframework.test.context.jdbc.Sql; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + @Sql({"/test-data/initialize.sql", "/test-data/finalize.sql"}) public class FetchUserMvcTests extends AbstractMvcTests { diff --git a/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/ForgotPasswordMvcTests.java b/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/ForgotPasswordMvcTests.java index 9d6ac5be..5eef92fe 100644 --- a/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/ForgotPasswordMvcTests.java +++ b/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/ForgotPasswordMvcTests.java @@ -1,14 +1,14 @@ package com.naturalprogrammer.spring.lemondemo; +import org.junit.Test; +import org.springframework.http.MediaType; + import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; -import org.junit.Test; -import org.springframework.http.MediaType; - public class ForgotPasswordMvcTests extends AbstractMvcTests { @Test diff --git a/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/LoginMvcTests.java b/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/LoginMvcTests.java index 0e25146d..587b5662 100644 --- a/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/LoginMvcTests.java +++ b/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/LoginMvcTests.java @@ -1,21 +1,18 @@ package com.naturalprogrammer.spring.lemondemo; -import static org.hamcrest.Matchers.containsString; -import static org.hamcrest.Matchers.hasSize; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; - +import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; +import com.naturalprogrammer.spring.lemondemo.entities.User; import org.junit.Test; import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; import org.springframework.test.context.jdbc.Sql; import org.springframework.test.web.servlet.MvcResult; -import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; -import com.naturalprogrammer.spring.lemondemo.entities.User; +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.hasSize; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; @Sql({"/test-data/initialize.sql", "/test-data/finalize.sql"}) public class LoginMvcTests extends AbstractMvcTests { diff --git a/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/RequestEmailChangeMvcTests.java b/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/RequestEmailChangeMvcTests.java index 01fc8694..89cf5482 100644 --- a/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/RequestEmailChangeMvcTests.java +++ b/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/RequestEmailChangeMvcTests.java @@ -1,5 +1,13 @@ package com.naturalprogrammer.spring.lemondemo; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; +import com.naturalprogrammer.spring.lemondemo.entities.User; +import org.junit.Assert; +import org.junit.Test; +import org.springframework.http.HttpHeaders; +import org.springframework.http.MediaType; + import static org.hamcrest.Matchers.hasItems; import static org.hamcrest.Matchers.hasSize; import static org.mockito.ArgumentMatchers.any; @@ -9,15 +17,6 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; -import org.junit.Assert; -import org.junit.Test; -import org.springframework.http.HttpHeaders; -import org.springframework.http.MediaType; - -import com.fasterxml.jackson.core.JsonProcessingException; -import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; -import com.naturalprogrammer.spring.lemondemo.entities.User; - public class RequestEmailChangeMvcTests extends AbstractMvcTests { private static final String NEW_EMAIL = "new.email@example.com"; diff --git a/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/ResendVerificationMailMvcTests.java b/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/ResendVerificationMailMvcTests.java index 66a40a0e..e9645d86 100644 --- a/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/ResendVerificationMailMvcTests.java +++ b/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/ResendVerificationMailMvcTests.java @@ -1,14 +1,14 @@ package com.naturalprogrammer.spring.lemondemo; +import org.junit.Test; +import org.springframework.http.HttpHeaders; + import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; -import org.junit.Test; -import org.springframework.http.HttpHeaders; - public class ResendVerificationMailMvcTests extends AbstractMvcTests { @Test diff --git a/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/ResetPasswordMvcTests.java b/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/ResetPasswordMvcTests.java index f332e8a4..48abfe62 100644 --- a/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/ResetPasswordMvcTests.java +++ b/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/ResetPasswordMvcTests.java @@ -1,20 +1,17 @@ package com.naturalprogrammer.spring.lemondemo; -import static org.hamcrest.Matchers.containsString; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; - +import com.fasterxml.jackson.core.JsonProcessingException; +import com.naturalprogrammer.spring.lemon.commons.domain.ResetPasswordForm; +import com.naturalprogrammer.spring.lemon.commons.security.GreenTokenService; +import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; import org.junit.Before; import org.junit.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.MediaType; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.naturalprogrammer.spring.lemon.commons.domain.ResetPasswordForm; -import com.naturalprogrammer.spring.lemon.commons.security.GreenTokenService; -import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; +import static org.hamcrest.Matchers.containsString; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; public class ResetPasswordMvcTests extends AbstractMvcTests { diff --git a/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/SignupMvcTests.java b/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/SignupMvcTests.java index 3deb00c7..d2fdb4e8 100644 --- a/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/SignupMvcTests.java +++ b/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/SignupMvcTests.java @@ -1,23 +1,18 @@ package com.naturalprogrammer.spring.lemondemo; -import static org.hamcrest.Matchers.containsString; -import static org.hamcrest.Matchers.hasItems; -import static org.hamcrest.Matchers.hasSize; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.verify; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; - +import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; +import com.naturalprogrammer.spring.lemondemo.entities.User; import org.junit.Assert; import org.junit.Test; import org.springframework.http.MediaType; import org.springframework.test.context.jdbc.Sql; -import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; -import com.naturalprogrammer.spring.lemondemo.entities.User; +import static org.hamcrest.Matchers.*; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; @Sql({"/test-data/initialize.sql", "/test-data/finalize.sql"}) public class SignupMvcTests extends AbstractMvcTests { diff --git a/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/UpdateUserMvcTests.java b/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/UpdateUserMvcTests.java index cbb53a49..9b1b7fbf 100644 --- a/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/UpdateUserMvcTests.java +++ b/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/UpdateUserMvcTests.java @@ -1,14 +1,8 @@ package com.naturalprogrammer.spring.lemondemo; -import static org.hamcrest.Matchers.containsString; -import static org.hamcrest.Matchers.hasSize; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.patch; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; - -import java.io.IOException; - +import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; +import com.naturalprogrammer.spring.lemon.commons.util.UserUtils; +import com.naturalprogrammer.spring.lemondemo.entities.User; import org.junit.Assert; import org.junit.Test; import org.springframework.beans.factory.annotation.Value; @@ -17,9 +11,12 @@ import org.springframework.http.MediaType; import org.springframework.test.context.jdbc.Sql; -import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; -import com.naturalprogrammer.spring.lemon.commons.util.UserUtils; -import com.naturalprogrammer.spring.lemondemo.entities.User; +import java.io.IOException; + +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.hasSize; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.patch; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; @Sql({"/test-data/initialize.sql", "/test-data/finalize.sql"}) public class UpdateUserMvcTests extends AbstractMvcTests { diff --git a/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/VerificationMvcTests.java b/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/VerificationMvcTests.java index 53ef2a61..fb7a69f1 100644 --- a/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/VerificationMvcTests.java +++ b/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/VerificationMvcTests.java @@ -1,20 +1,17 @@ package com.naturalprogrammer.spring.lemondemo; -import static org.hamcrest.Matchers.containsString; -import static org.hamcrest.Matchers.hasSize; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; - +import com.naturalprogrammer.spring.lemon.commons.security.GreenTokenService; +import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; +import com.naturalprogrammer.spring.lemondemo.entities.User; import org.junit.Before; import org.junit.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.MediaType; -import com.naturalprogrammer.spring.lemon.commons.security.GreenTokenService; -import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; -import com.naturalprogrammer.spring.lemondemo.entities.User; +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.hasSize; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; public class VerificationMvcTests extends AbstractMvcTests { diff --git a/lemon-demo-reactive/pom.xml b/lemon-demo-reactive/pom.xml index 9f146cb0..df4c895a 100644 --- a/lemon-demo-reactive/pom.xml +++ b/lemon-demo-reactive/pom.xml @@ -13,7 +13,7 @@ com.naturalprogrammer spring-lemon - 1.0.0.RC3 + 1.0.0.RC4 diff --git a/lemon-demo-reactive/src/main/java/com/naturalprogrammer/spring/lemondemo/controllers/MyController.java b/lemon-demo-reactive/src/main/java/com/naturalprogrammer/spring/lemondemo/controllers/MyController.java index f6737525..a9914e42 100644 --- a/lemon-demo-reactive/src/main/java/com/naturalprogrammer/spring/lemondemo/controllers/MyController.java +++ b/lemon-demo-reactive/src/main/java/com/naturalprogrammer/spring/lemondemo/controllers/MyController.java @@ -1,19 +1,17 @@ package com.naturalprogrammer.spring.lemondemo.controllers; -import org.bson.types.ObjectId; -import org.springframework.http.server.reactive.ServerHttpResponse; -import org.springframework.validation.annotation.Validated; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - import com.fasterxml.jackson.annotation.JsonView; import com.naturalprogrammer.spring.lemon.commons.security.UserDto; import com.naturalprogrammer.spring.lemon.commons.util.UserUtils; import com.naturalprogrammer.spring.lemon.commons.util.UserUtils.SignUpValidation; import com.naturalprogrammer.spring.lemondemo.domain.User; import com.naturalprogrammer.spring.lemonreactive.LemonReactiveController; - +import org.bson.types.ObjectId; +import org.springframework.http.server.reactive.ServerHttpResponse; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; import reactor.core.publisher.Mono; @RestController diff --git a/lemon-demo-reactive/src/main/java/com/naturalprogrammer/spring/lemondemo/domain/User.java b/lemon-demo-reactive/src/main/java/com/naturalprogrammer/spring/lemondemo/domain/User.java index 20e12dfd..b12dfd8f 100644 --- a/lemon-demo-reactive/src/main/java/com/naturalprogrammer/spring/lemondemo/domain/User.java +++ b/lemon-demo-reactive/src/main/java/com/naturalprogrammer/spring/lemondemo/domain/User.java @@ -1,21 +1,18 @@ package com.naturalprogrammer.spring.lemondemo.domain; -import java.io.Serializable; - -import javax.validation.constraints.NotBlank; -import javax.validation.constraints.Size; - -import org.bson.types.ObjectId; -import org.springframework.data.annotation.TypeAlias; -import org.springframework.data.mongodb.core.mapping.Document; - import com.fasterxml.jackson.annotation.JsonView; import com.naturalprogrammer.spring.lemon.commons.util.UserUtils; import com.naturalprogrammer.spring.lemonreactive.domain.AbstractMongoUser; - import lombok.Getter; import lombok.Setter; import lombok.ToString; +import org.bson.types.ObjectId; +import org.springframework.data.annotation.TypeAlias; +import org.springframework.data.mongodb.core.mapping.Document; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.Size; +import java.io.Serializable; @Getter @Setter @TypeAlias("User") diff --git a/lemon-demo-reactive/src/main/java/com/naturalprogrammer/spring/lemondemo/repositories/UserRepository.java b/lemon-demo-reactive/src/main/java/com/naturalprogrammer/spring/lemondemo/repositories/UserRepository.java index ff841fc9..fcea2d33 100644 --- a/lemon-demo-reactive/src/main/java/com/naturalprogrammer/spring/lemondemo/repositories/UserRepository.java +++ b/lemon-demo-reactive/src/main/java/com/naturalprogrammer/spring/lemondemo/repositories/UserRepository.java @@ -1,8 +1,8 @@ package com.naturalprogrammer.spring.lemondemo.repositories; -import org.bson.types.ObjectId; import com.naturalprogrammer.spring.lemondemo.domain.User; import com.naturalprogrammer.spring.lemonreactive.domain.AbstractMongoUserRepository; +import org.bson.types.ObjectId; public interface UserRepository extends AbstractMongoUserRepository { diff --git a/lemon-demo-reactive/src/main/java/com/naturalprogrammer/spring/lemondemo/services/MyService.java b/lemon-demo-reactive/src/main/java/com/naturalprogrammer/spring/lemondemo/services/MyService.java index 8b100a2a..d61c2a3b 100644 --- a/lemon-demo-reactive/src/main/java/com/naturalprogrammer/spring/lemondemo/services/MyService.java +++ b/lemon-demo-reactive/src/main/java/com/naturalprogrammer/spring/lemondemo/services/MyService.java @@ -1,14 +1,13 @@ package com.naturalprogrammer.spring.lemondemo.services; -import java.util.Map; - +import com.naturalprogrammer.spring.lemon.commons.security.UserDto; +import com.naturalprogrammer.spring.lemondemo.domain.User; +import com.naturalprogrammer.spring.lemonreactive.LemonReactiveService; import org.bson.types.ObjectId; import org.springframework.security.oauth2.core.oidc.StandardClaimNames; import org.springframework.stereotype.Service; -import com.naturalprogrammer.spring.lemon.commons.security.UserDto; -import com.naturalprogrammer.spring.lemondemo.domain.User; -import com.naturalprogrammer.spring.lemonreactive.LemonReactiveService; +import java.util.Map; @Service public class MyService extends LemonReactiveService { diff --git a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/AbstractTests.java b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/AbstractTests.java index eec0e758..47cc68eb 100644 --- a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/AbstractTests.java +++ b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/AbstractTests.java @@ -1,23 +1,22 @@ package com.naturalprogrammer.spring.lemondemo; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - -import java.util.Arrays; -import java.util.stream.Collectors; - +import com.naturalprogrammer.spring.lemon.commons.mail.MailSender; +import com.naturalprogrammer.spring.lemondemo.dto.TestErrorResponse; +import com.naturalprogrammer.spring.lemondemo.dto.TestLemonFieldError; import org.junit.Before; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.data.mongodb.core.MongoTemplate; +import org.springframework.data.mongodb.core.ReactiveMongoTemplate; import org.springframework.test.context.junit4.SpringRunner; import org.springframework.test.web.reactive.server.EntityExchangeResult; -import com.naturalprogrammer.spring.lemon.commons.mail.MailSender; -import com.naturalprogrammer.spring.lemondemo.dto.TestErrorResponse; -import com.naturalprogrammer.spring.lemondemo.dto.TestLemonFieldError; +import java.util.Arrays; +import java.util.stream.Collectors; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; @RunWith(SpringRunner.class) @SpringBootTest({ @@ -29,7 +28,7 @@ public abstract class AbstractTests { @Autowired - protected MongoTemplate mongoTemplate; + protected ReactiveMongoTemplate mongoTemplate; @Autowired protected MyTestUtils testUtils; diff --git a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/BasicTests.java b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/BasicTests.java index 7e1b0daf..8c86eb2a 100644 --- a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/BasicTests.java +++ b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/BasicTests.java @@ -1,13 +1,10 @@ package com.naturalprogrammer.spring.lemondemo; -import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.ADMIN_ID; -import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.CLIENT; -import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.TOKENS; -import static com.naturalprogrammer.spring.lemondemo.controllers.MyController.BASE_URI; - +import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; import org.junit.Test; -import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; +import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.*; +import static com.naturalprogrammer.spring.lemondemo.controllers.MyController.BASE_URI; public class BasicTests extends AbstractTests { diff --git a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/ChangeEmailTests.java b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/ChangeEmailTests.java index 3d2e7806..254e8b12 100644 --- a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/ChangeEmailTests.java +++ b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/ChangeEmailTests.java @@ -1,15 +1,8 @@ package com.naturalprogrammer.spring.lemondemo; -import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.ADMIN_ID; -import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.CLIENT; -import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.TOKENS; -import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.UNVERIFIED_USER_EMAIL; -import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.UNVERIFIED_USER_ID; -import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.USER_ID; -import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.USER_PASSWORD; -import static com.naturalprogrammer.spring.lemondemo.controllers.MyController.BASE_URI; -import static org.springframework.web.reactive.function.BodyInserters.fromFormData; - +import com.naturalprogrammer.spring.lemon.commons.security.GreenTokenService; +import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; +import com.naturalprogrammer.spring.lemondemo.domain.User; import org.junit.Assert; import org.junit.Before; import org.junit.Test; @@ -18,9 +11,9 @@ import org.springframework.http.HttpStatus; import org.springframework.test.web.reactive.server.WebTestClient.ResponseSpec; -import com.naturalprogrammer.spring.lemon.commons.security.GreenTokenService; -import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; -import com.naturalprogrammer.spring.lemondemo.domain.User; +import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.*; +import static com.naturalprogrammer.spring.lemondemo.controllers.MyController.BASE_URI; +import static org.springframework.web.reactive.function.BodyInserters.fromFormData; public class ChangeEmailTests extends AbstractTests { @@ -34,9 +27,9 @@ public class ChangeEmailTests extends AbstractTests { @Before public void setUp() { - User user = mongoTemplate.findById(UNVERIFIED_USER_ID, User.class); + User user = mongoTemplate.findById(UNVERIFIED_USER_ID, User.class).block(); user.setNewEmail(NEW_EMAIL); - mongoTemplate.save(user); + mongoTemplate.save(user).block(); changeEmailCode = greenTokenService.createToken( GreenTokenService.CHANGE_EMAIL_AUDIENCE, @@ -52,7 +45,7 @@ public void testChangeEmail() throws Exception { .expectHeader().valueMatches(LecUtils.TOKEN_RESPONSE_HEADER_NAME, ".*\\..*") .expectBody().jsonPath("$.id").isEqualTo(UNVERIFIED_USER_ID.toString()); - User updatedUser = mongoTemplate.findById(UNVERIFIED_USER_ID, User.class); + User updatedUser = mongoTemplate.findById(UNVERIFIED_USER_ID, User.class).block(); Assert.assertNull(updatedUser.getNewEmail()); Assert.assertEquals(NEW_EMAIL, updatedUser.getEmail()); @@ -106,9 +99,9 @@ public void testChangeEmailObsoleteCode() throws Exception { // credentials updated after the request for email change was made Thread.sleep(1L); - User user = mongoTemplate.findById(UNVERIFIED_USER_ID, User.class); + User user = mongoTemplate.findById(UNVERIFIED_USER_ID, User.class).block(); user.setCredentialsUpdatedMillis(System.currentTimeMillis()); - mongoTemplate.save(user); + mongoTemplate.save(user).block(); // A new auth token is needed, because old one would be obsolete! String authToken = testUtils.login(UNVERIFIED_USER_EMAIL, USER_PASSWORD); @@ -142,9 +135,9 @@ public void testChangeEmailWithoutAnyRequest() throws Exception { public void testChangeEmailNonUniqueEmail() throws Exception { // Some other user changed to the same email - User user = mongoTemplate.findById(ADMIN_ID, User.class); + User user = mongoTemplate.findById(ADMIN_ID, User.class).block(); user.setEmail(NEW_EMAIL); - mongoTemplate.save(user); + mongoTemplate.save(user).block(); // Blank token changeEmailResponse(changeEmailCode) diff --git a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/ChangePasswordTests.java b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/ChangePasswordTests.java index 9a473140..6d0c1cbb 100644 --- a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/ChangePasswordTests.java +++ b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/ChangePasswordTests.java @@ -1,28 +1,18 @@ package com.naturalprogrammer.spring.lemondemo; -import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.ADMIN_ID; -import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.ADMIN_PASSWORD; -import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.CLIENT; -import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.TOKENS; -import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.UNVERIFIED_ADMIN_ID; -import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.UNVERIFIED_USER_EMAIL; -import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.UNVERIFIED_USER_ID; -import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.USER_ID; -import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.USER_PASSWORD; -import static com.naturalprogrammer.spring.lemondemo.controllers.MyController.BASE_URI; - +import com.naturalprogrammer.spring.lemon.commons.domain.ChangePasswordForm; +import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; +import com.naturalprogrammer.spring.lemondemo.dto.TestErrorResponse; import org.bson.types.ObjectId; import org.junit.Test; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; - -import com.naturalprogrammer.spring.lemon.commons.domain.ChangePasswordForm; -import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; -import com.naturalprogrammer.spring.lemondemo.dto.TestErrorResponse; - import reactor.core.publisher.Mono; +import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.*; +import static com.naturalprogrammer.spring.lemondemo.controllers.MyController.BASE_URI; + public class ChangePasswordTests extends AbstractTests { private static final String NEW_PASSWORD = "a-new-password"; diff --git a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/FetchNewTokenTests.java b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/FetchNewTokenTests.java index 84945f38..18a6c497 100644 --- a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/FetchNewTokenTests.java +++ b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/FetchNewTokenTests.java @@ -1,21 +1,15 @@ package com.naturalprogrammer.spring.lemondemo; -import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.ADMIN_EMAIL; -import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.ADMIN_ID; -import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.CLIENT; -import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.TOKENS; -import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.UNVERIFIED_USER_EMAIL; -import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.UNVERIFIED_USER_ID; -import static com.naturalprogrammer.spring.lemondemo.controllers.MyController.BASE_URI; -import static org.junit.Assert.assertNotNull; -import static org.springframework.web.reactive.function.BodyInserters.fromFormData; - +import com.naturalprogrammer.spring.lemondemo.dto.TestToken; import org.junit.Test; import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; import org.springframework.test.web.reactive.server.EntityExchangeResult; -import com.naturalprogrammer.spring.lemondemo.dto.TestToken; +import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.*; +import static com.naturalprogrammer.spring.lemondemo.controllers.MyController.BASE_URI; +import static org.junit.Assert.assertNotNull; +import static org.springframework.web.reactive.function.BodyInserters.fromFormData; public class FetchNewTokenTests extends AbstractTests { diff --git a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/FetchUserTests.java b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/FetchUserTests.java index d9cd4c9f..8a118e46 100644 --- a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/FetchUserTests.java +++ b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/FetchUserTests.java @@ -1,20 +1,15 @@ package com.naturalprogrammer.spring.lemondemo; -import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.ADMIN_EMAIL; -import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.ADMIN_ID; -import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.CLIENT; -import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.TOKENS; -import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.UNVERIFIED_USER_EMAIL; -import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.UNVERIFIED_USER_ID; -import static com.naturalprogrammer.spring.lemondemo.controllers.MyController.BASE_URI; -import static org.springframework.web.reactive.function.BodyInserters.fromFormData; - import org.bson.types.ObjectId; import org.junit.Test; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; +import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.*; +import static com.naturalprogrammer.spring.lemondemo.controllers.MyController.BASE_URI; +import static org.springframework.web.reactive.function.BodyInserters.fromFormData; + public class FetchUserTests extends AbstractTests { @Test diff --git a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/ForgotPasswordTests.java b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/ForgotPasswordTests.java index 1658e662..e642bf2d 100644 --- a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/ForgotPasswordTests.java +++ b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/ForgotPasswordTests.java @@ -1,5 +1,9 @@ package com.naturalprogrammer.spring.lemondemo; +import org.junit.Test; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; + import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.ADMIN_EMAIL; import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.CLIENT; import static com.naturalprogrammer.spring.lemondemo.controllers.MyController.BASE_URI; @@ -8,10 +12,6 @@ import static org.mockito.Mockito.verify; import static org.springframework.web.reactive.function.BodyInserters.fromFormData; -import org.junit.Test; -import org.springframework.http.HttpStatus; -import org.springframework.http.MediaType; - public class ForgotPasswordTests extends AbstractTests { @Test diff --git a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/LoginTests.java b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/LoginTests.java index 15d5e6de..f3e4a7a7 100644 --- a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/LoginTests.java +++ b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/LoginTests.java @@ -1,23 +1,15 @@ package com.naturalprogrammer.spring.lemondemo; -import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.ADMIN_EMAIL; -import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.ADMIN_ID; -import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.ADMIN_PASSWORD; -import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.CLIENT; -import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.TOKENS; -import static com.naturalprogrammer.spring.lemondemo.controllers.MyController.BASE_URI; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; -import static org.springframework.web.reactive.function.BodyInserters.fromFormData; - -import org.junit.Test; -import org.springframework.http.HttpHeaders; - import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; import com.naturalprogrammer.spring.lemondemo.domain.User; import com.naturalprogrammer.spring.lemondemo.dto.TestUserDto; +import org.junit.Test; +import org.springframework.http.HttpHeaders; + +import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.*; +import static com.naturalprogrammer.spring.lemondemo.controllers.MyController.BASE_URI; +import static org.junit.Assert.*; +import static org.springframework.web.reactive.function.BodyInserters.fromFormData; public class LoginTests extends AbstractTests { @@ -63,9 +55,9 @@ public void testLoginTokenExpiry() throws Exception { @Test public void testObsoleteToken() throws Exception { - User user = mongoTemplate.findById(ADMIN_ID, User.class); + User user = mongoTemplate.findById(ADMIN_ID, User.class).block(); user.setCredentialsUpdatedMillis(System.currentTimeMillis()); - mongoTemplate.save(user); + mongoTemplate.save(user).block(); CLIENT.get() .uri(BASE_URI + "/ping") diff --git a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/MyTestUtils.java b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/MyTestUtils.java index 7d2c400d..dcf98f27 100644 --- a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/MyTestUtils.java +++ b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/MyTestUtils.java @@ -1,29 +1,28 @@ package com.naturalprogrammer.spring.lemondemo; -import static com.naturalprogrammer.spring.lemondemo.controllers.MyController.BASE_URI; -import static org.springframework.web.reactive.function.BodyInserters.fromFormData; - -import java.time.Duration; -import java.util.Arrays; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; - +import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; +import com.naturalprogrammer.spring.lemondemo.domain.User; +import com.naturalprogrammer.spring.lemondemo.dto.TestUserDto; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.bson.types.ObjectId; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationContext; -import org.springframework.data.mongodb.core.MongoTemplate; +import org.springframework.data.mongodb.core.ReactiveMongoTemplate; import org.springframework.http.HttpHeaders; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.stereotype.Component; import org.springframework.test.web.reactive.server.WebTestClient; import org.springframework.test.web.reactive.server.WebTestClient.ResponseSpec; -import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; -import com.naturalprogrammer.spring.lemondemo.domain.User; -import com.naturalprogrammer.spring.lemondemo.dto.TestUserDto; +import java.time.Duration; +import java.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; + +import static com.naturalprogrammer.spring.lemondemo.controllers.MyController.BASE_URI; +import static org.springframework.web.reactive.function.BodyInserters.fromFormData; @Component public class MyTestUtils { @@ -52,7 +51,7 @@ public class MyTestUtils { private PasswordEncoder passwordEncoder; @Autowired - private MongoTemplate mongoTemplate; + private ReactiveMongoTemplate mongoTemplate; public MyTestUtils(ApplicationContext context) { CLIENT = WebTestClient @@ -102,7 +101,7 @@ public ResponseSpec contextResponse(String token) { // public void initDatabase() { - mongoTemplate.dropCollection("usr"); + mongoTemplate.dropCollection("usr").block(); log.debug("Creating users ... "); createUser(ADMIN_ID, ADMIN_EMAIL, ADMIN_PASSWORD, "Admin 1", "ADMIN"); @@ -125,7 +124,7 @@ private void createUser(ObjectId id, String email, String password, String name, user.setCredentialsUpdatedMillis(0L); user.setRoles(new HashSet(Arrays.asList(roles))); - mongoTemplate.insert(user); + mongoTemplate.insert(user).block(); TOKENS.put(user.getId(), login(user.getEmail(), password)); } } diff --git a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/RequestEmailChangeTests.java b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/RequestEmailChangeTests.java index f72a5ae4..ca17e25a 100644 --- a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/RequestEmailChangeTests.java +++ b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/RequestEmailChangeTests.java @@ -1,19 +1,9 @@ package com.naturalprogrammer.spring.lemondemo; -import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.ADMIN_EMAIL; -import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.ADMIN_ID; -import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.CLIENT; -import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.TOKENS; -import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.UNVERIFIED_ADMIN_ID; -import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.UNVERIFIED_USER_EMAIL; -import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.UNVERIFIED_USER_ID; -import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.USER_ID; -import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.USER_PASSWORD; -import static com.naturalprogrammer.spring.lemondemo.controllers.MyController.BASE_URI; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.verify; - +import com.fasterxml.jackson.core.JsonProcessingException; +import com.naturalprogrammer.spring.lemondemo.domain.User; +import com.naturalprogrammer.spring.lemondemo.dto.TestEmailForm; +import com.naturalprogrammer.spring.lemondemo.dto.TestErrorResponse; import org.bson.types.ObjectId; import org.junit.Assert; import org.junit.Test; @@ -21,14 +11,14 @@ import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.test.web.reactive.server.WebTestClient.BodySpec; - -import com.fasterxml.jackson.core.JsonProcessingException; -import com.naturalprogrammer.spring.lemondemo.domain.User; -import com.naturalprogrammer.spring.lemondemo.dto.TestEmailForm; -import com.naturalprogrammer.spring.lemondemo.dto.TestErrorResponse; - import reactor.core.publisher.Mono; +import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.*; +import static com.naturalprogrammer.spring.lemondemo.controllers.MyController.BASE_URI; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; + public class RequestEmailChangeTests extends AbstractTests { private static final String NEW_EMAIL = "new.email@example.com"; @@ -55,7 +45,7 @@ public void testRequestEmailChange() { verify(mailSender).send(any()); - User updatedUser = mongoTemplate.findById(UNVERIFIED_USER_ID, User.class); + User updatedUser = mongoTemplate.findById(UNVERIFIED_USER_ID, User.class).block(); Assert.assertEquals(NEW_EMAIL, updatedUser.getNewEmail()); Assert.assertEquals(UNVERIFIED_USER_EMAIL, updatedUser.getEmail()); } @@ -74,7 +64,7 @@ public void testGoodAdminRequestEmailChange() throws Exception { .exchange() .expectStatus().isNoContent(); - User updatedUser = mongoTemplate.findById(UNVERIFIED_USER_ID, User.class); + User updatedUser = mongoTemplate.findById(UNVERIFIED_USER_ID, User.class).block(); Assert.assertEquals(NEW_EMAIL, updatedUser.getNewEmail()); } @@ -223,7 +213,7 @@ public void testRequestEmailChangeWithInvalidData() { private void assertNotChanged() { - User updatedUser = mongoTemplate.findById(UNVERIFIED_USER_ID, User.class); + User updatedUser = mongoTemplate.findById(UNVERIFIED_USER_ID, User.class).block(); Assert.assertNull(updatedUser.getNewEmail()); } } diff --git a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/ResendVerificationMailTests.java b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/ResendVerificationMailTests.java index 5633a3e0..9bff18f5 100644 --- a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/ResendVerificationMailTests.java +++ b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/ResendVerificationMailTests.java @@ -1,23 +1,17 @@ package com.naturalprogrammer.spring.lemondemo; -import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.ADMIN_ID; -import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.BLOCKED_ADMIN_ID; -import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.CLIENT; -import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.TOKENS; -import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.UNVERIFIED_ADMIN_ID; -import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.UNVERIFIED_USER_ID; -import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.USER_ID; -import static com.naturalprogrammer.spring.lemondemo.controllers.MyController.BASE_URI; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.verify; - import org.bson.types.ObjectId; import org.junit.Test; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.test.web.reactive.server.WebTestClient.ResponseSpec; +import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.*; +import static com.naturalprogrammer.spring.lemondemo.controllers.MyController.BASE_URI; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; + public class ResendVerificationMailTests extends AbstractTests { @Test diff --git a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/ResetPasswordTests.java b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/ResetPasswordTests.java index 47dc69e4..12a84bca 100644 --- a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/ResetPasswordTests.java +++ b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/ResetPasswordTests.java @@ -1,23 +1,19 @@ package com.naturalprogrammer.spring.lemondemo; -import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.ADMIN_EMAIL; -import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.ADMIN_ID; -import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.CLIENT; -import static com.naturalprogrammer.spring.lemondemo.controllers.MyController.BASE_URI; - +import com.naturalprogrammer.spring.lemon.commons.security.GreenTokenService; +import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; +import com.naturalprogrammer.spring.lemondemo.dto.TestResetPasswordForm; import org.junit.Before; import org.junit.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.test.web.reactive.server.WebTestClient.ResponseSpec; - -import com.naturalprogrammer.spring.lemon.commons.security.GreenTokenService; -import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; -import com.naturalprogrammer.spring.lemondemo.dto.TestResetPasswordForm; - import reactor.core.publisher.Mono; +import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.*; +import static com.naturalprogrammer.spring.lemondemo.controllers.MyController.BASE_URI; + public class ResetPasswordTests extends AbstractTests { private String forgotPasswordCode; diff --git a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/SignupTests.java b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/SignupTests.java index 1ea5f527..01d624a0 100644 --- a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/SignupTests.java +++ b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/SignupTests.java @@ -1,39 +1,30 @@ package com.naturalprogrammer.spring.lemondemo; -import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.ADMIN_EMAIL; -import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.CLIENT; -import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.UNVERIFIED_USER_ID; -import static com.naturalprogrammer.spring.lemondemo.controllers.MyController.BASE_URI; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.verify; -import static org.springframework.data.mongodb.core.query.Criteria.where; -import static org.springframework.data.mongodb.core.query.Query.query; - -import java.util.Arrays; -import java.util.Collection; -import java.util.stream.Collectors; - -import org.junit.Test; -import org.springframework.http.HttpStatus; -import org.springframework.http.MediaType; -import org.springframework.test.web.reactive.server.WebTestClient.ResponseSpec; - import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; import com.naturalprogrammer.spring.lemondemo.domain.User; import com.naturalprogrammer.spring.lemondemo.dto.TestErrorResponse; import com.naturalprogrammer.spring.lemondemo.dto.TestLemonFieldError; import com.naturalprogrammer.spring.lemondemo.dto.TestUser; import com.naturalprogrammer.spring.lemondemo.dto.TestUserDto; - +import org.junit.Test; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.test.web.reactive.server.WebTestClient.ResponseSpec; import reactor.core.publisher.Mono; +import java.util.Arrays; +import java.util.Collection; +import java.util.stream.Collectors; + +import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.*; +import static com.naturalprogrammer.spring.lemondemo.controllers.MyController.BASE_URI; +import static org.junit.Assert.*; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; +import static org.springframework.data.mongodb.core.query.Criteria.where; +import static org.springframework.data.mongodb.core.query.Query.query; + public class SignupTests extends AbstractTests { @Test @@ -63,7 +54,7 @@ public void testSignup() throws Exception { // Ensure that password got encrypted assertNotEquals("user123", mongoTemplate.findOne(query(where("email").is("user.foo@example.com")), - User.class).getPassword()); + User.class).block().getPassword()); } @Test diff --git a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/TestConfiguration.java b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/TestConfiguration.java new file mode 100644 index 00000000..a163c84d --- /dev/null +++ b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/TestConfiguration.java @@ -0,0 +1,14 @@ +package com.naturalprogrammer.spring.lemondemo; + +import org.springframework.context.annotation.Configuration; +import org.springframework.data.mongodb.MongoDatabaseFactory; +import org.springframework.data.mongodb.core.MongoTemplate; + +@Configuration +public class TestConfiguration { + + //@Bean + public MongoTemplate mongoTemplate(MongoDatabaseFactory mongoDbFactory) { + return new MongoTemplate(mongoDbFactory); + } +} diff --git a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/UpdateUserTests.java b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/UpdateUserTests.java index faff1ecd..772ce683 100644 --- a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/UpdateUserTests.java +++ b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/UpdateUserTests.java @@ -1,16 +1,9 @@ package com.naturalprogrammer.spring.lemondemo; -import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.ADMIN_ID; -import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.BLOCKED_ADMIN_ID; -import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.CLIENT; -import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.TOKENS; -import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.UNVERIFIED_ADMIN_ID; -import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.UNVERIFIED_USER_EMAIL; -import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.UNVERIFIED_USER_ID; -import static com.naturalprogrammer.spring.lemondemo.controllers.MyController.BASE_URI; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - +import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; +import com.naturalprogrammer.spring.lemon.commons.util.UserUtils; +import com.naturalprogrammer.spring.lemondemo.domain.User; +import com.naturalprogrammer.spring.lemondemo.dto.TestUserDto; import org.bson.types.ObjectId; import org.junit.Test; import org.springframework.beans.factory.annotation.Value; @@ -21,10 +14,10 @@ import org.springframework.test.web.reactive.server.WebTestClient.ResponseSpec; import org.springframework.web.reactive.function.BodyInserters; -import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; -import com.naturalprogrammer.spring.lemon.commons.util.UserUtils; -import com.naturalprogrammer.spring.lemondemo.domain.User; -import com.naturalprogrammer.spring.lemondemo.dto.TestUserDto; +import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.*; +import static com.naturalprogrammer.spring.lemondemo.controllers.MyController.BASE_URI; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; public class UpdateUserTests extends AbstractTests { @@ -67,7 +60,7 @@ public void testUpdateSelf() throws Exception { assertTrue(userDto.getRoles().contains(UserUtils.Role.UNVERIFIED)); }); - User user = mongoTemplate.findById(UNVERIFIED_USER_ID, User.class); + User user = mongoTemplate.findById(UNVERIFIED_USER_ID, User.class).block(); // Ensure that data changed properly assertEquals(UNVERIFIED_USER_EMAIL, user.getEmail()); @@ -106,7 +99,7 @@ public void testGoodAdminCanUpdateOther() throws Exception { assertTrue(userDto.getRoles().contains(UserUtils.Role.ADMIN)); }); - User user = mongoTemplate.findById(UNVERIFIED_USER_ID, User.class); + User user = mongoTemplate.findById(UNVERIFIED_USER_ID, User.class).block(); // Ensure that data changed properly assertEquals(UNVERIFIED_USER_EMAIL, user.getEmail()); @@ -169,7 +162,7 @@ public void goodAdminCanNotUpdateSelfRoles() throws Exception { assertTrue(userDto.getRoles().contains(UserUtils.Role.ADMIN)); }); - User user = mongoTemplate.findById(ADMIN_ID, User.class); + User user = mongoTemplate.findById(ADMIN_ID, User.class).block(); assertEquals(1, user.getRoles().size()); } diff --git a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/VerificationTests.java b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/VerificationTests.java index 30b3a4bc..3f715498 100644 --- a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/VerificationTests.java +++ b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/VerificationTests.java @@ -1,14 +1,8 @@ package com.naturalprogrammer.spring.lemondemo; -import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.CLIENT; -import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.UNVERIFIED_USER_EMAIL; -import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.UNVERIFIED_USER_ID; -import static com.naturalprogrammer.spring.lemondemo.controllers.MyController.BASE_URI; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; -import static org.springframework.web.reactive.function.BodyInserters.fromFormData; - +import com.naturalprogrammer.spring.lemon.commons.security.GreenTokenService; +import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; +import com.naturalprogrammer.spring.lemondemo.dto.TestUserDto; import org.bson.types.ObjectId; import org.junit.Before; import org.junit.Test; @@ -16,9 +10,10 @@ import org.springframework.http.HttpStatus; import org.springframework.test.web.reactive.server.WebTestClient.ResponseSpec; -import com.naturalprogrammer.spring.lemon.commons.security.GreenTokenService; -import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; -import com.naturalprogrammer.spring.lemondemo.dto.TestUserDto; +import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.*; +import static com.naturalprogrammer.spring.lemondemo.controllers.MyController.BASE_URI; +import static org.junit.Assert.*; +import static org.springframework.web.reactive.function.BodyInserters.fromFormData; public class VerificationTests extends AbstractTests { diff --git a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/dto/TestErrorResponse.java b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/dto/TestErrorResponse.java index 9c4d9891..4fb59bbb 100644 --- a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/dto/TestErrorResponse.java +++ b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/dto/TestErrorResponse.java @@ -1,10 +1,10 @@ package com.naturalprogrammer.spring.lemondemo.dto; -import java.util.Collection; - import lombok.Getter; import lombok.Setter; +import java.util.Collection; + /** * Error DTO, to be sent as response body * in case of errors diff --git a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/dto/TestUserDto.java b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/dto/TestUserDto.java index d5b15cc2..d7bafc59 100644 --- a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/dto/TestUserDto.java +++ b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/dto/TestUserDto.java @@ -1,14 +1,12 @@ package com.naturalprogrammer.spring.lemondemo.dto; -import java.util.HashSet; -import java.util.Set; - -import org.bson.types.ObjectId; - import com.naturalprogrammer.spring.lemondemo.domain.User.Tag; - import lombok.Getter; import lombok.Setter; +import org.bson.types.ObjectId; + +import java.util.HashSet; +import java.util.Set; @Getter @Setter public class TestUserDto { diff --git a/pom.xml b/pom.xml index 779fe9f4..2cf3b376 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.naturalprogrammer spring-lemon - 1.0.0.RC3 + 1.0.0.RC4 pom spring-lemon @@ -15,7 +15,7 @@ org.springframework.boot spring-boot-starter-parent - 2.2.0.RELEASE + 2.3.0.RELEASE diff --git a/spring-lemon-commons-jpa/pom.xml b/spring-lemon-commons-jpa/pom.xml index 9f2a0e1b..91e1dda9 100644 --- a/spring-lemon-commons-jpa/pom.xml +++ b/spring-lemon-commons-jpa/pom.xml @@ -13,7 +13,7 @@ com.naturalprogrammer spring-lemon - 1.0.0.RC3 + 1.0.0.RC4 diff --git a/spring-lemon-commons-jpa/src/main/java/com/naturalprogrammer/spring/lemon/commonsjpa/LecjUtils.java b/spring-lemon-commons-jpa/src/main/java/com/naturalprogrammer/spring/lemon/commonsjpa/LecjUtils.java index 3f69ff9c..62a4862d 100644 --- a/spring-lemon-commons-jpa/src/main/java/com/naturalprogrammer/spring/lemon/commonsjpa/LecjUtils.java +++ b/spring-lemon-commons-jpa/src/main/java/com/naturalprogrammer/spring/lemon/commonsjpa/LecjUtils.java @@ -1,11 +1,11 @@ package com.naturalprogrammer.spring.lemon.commonsjpa; -import java.io.Serializable; - +import com.naturalprogrammer.spring.lemon.exceptions.VersionException; import org.springframework.transaction.support.TransactionSynchronizationAdapter; import org.springframework.transaction.support.TransactionSynchronizationManager; -import com.naturalprogrammer.spring.lemon.exceptions.VersionException; +import java.io.Serializable; +import java.util.Objects; public class LecjUtils { @@ -38,7 +38,7 @@ public void afterCommit() { public static void ensureCorrectVersion(LemonEntity original, LemonEntity updated) { - if (original.getVersion() != updated.getVersion()) + if (!Objects.equals(original.getVersion(), updated.getVersion())) throw new VersionException(original.getClass().getSimpleName(), original.getId().toString()); } } diff --git a/spring-lemon-commons-jpa/src/main/java/com/naturalprogrammer/spring/lemon/commonsjpa/LemonCommonsJpaAutoConfiguration.java b/spring-lemon-commons-jpa/src/main/java/com/naturalprogrammer/spring/lemon/commonsjpa/LemonCommonsJpaAutoConfiguration.java index 7b51d479..b71fb0ed 100644 --- a/spring-lemon-commons-jpa/src/main/java/com/naturalprogrammer/spring/lemon/commonsjpa/LemonCommonsJpaAutoConfiguration.java +++ b/spring-lemon-commons-jpa/src/main/java/com/naturalprogrammer/spring/lemon/commonsjpa/LemonCommonsJpaAutoConfiguration.java @@ -1,12 +1,11 @@ package com.naturalprogrammer.spring.lemon.commonsjpa; +import com.naturalprogrammer.spring.lemon.commonsweb.LemonCommonsWebAutoConfiguration; import org.springframework.boot.autoconfigure.AutoConfigureBefore; import org.springframework.context.annotation.Configuration; import org.springframework.data.jpa.repository.config.EnableJpaAuditing; import org.springframework.transaction.annotation.EnableTransactionManagement; -import com.naturalprogrammer.spring.lemon.commonsweb.LemonCommonsWebAutoConfiguration; - @Configuration @EnableTransactionManagement @EnableJpaAuditing diff --git a/spring-lemon-commons-jpa/src/main/java/com/naturalprogrammer/spring/lemon/commonsjpa/LemonEntity.java b/spring-lemon-commons-jpa/src/main/java/com/naturalprogrammer/spring/lemon/commonsjpa/LemonEntity.java index 50ac1785..88b69fe8 100644 --- a/spring-lemon-commons-jpa/src/main/java/com/naturalprogrammer/spring/lemon/commonsjpa/LemonEntity.java +++ b/spring-lemon-commons-jpa/src/main/java/com/naturalprogrammer/spring/lemon/commonsjpa/LemonEntity.java @@ -1,25 +1,22 @@ package com.naturalprogrammer.spring.lemon.commonsjpa; -import java.io.Serializable; -import java.util.Date; - -import javax.persistence.MappedSuperclass; -import javax.persistence.Temporal; -import javax.persistence.TemporalType; -import javax.persistence.Version; - +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.naturalprogrammer.spring.lemon.commons.security.PermissionEvaluatorEntity; +import com.naturalprogrammer.spring.lemon.commons.security.UserDto; +import lombok.Getter; +import lombok.Setter; import org.springframework.data.annotation.CreatedBy; import org.springframework.data.annotation.CreatedDate; import org.springframework.data.annotation.LastModifiedBy; import org.springframework.data.annotation.LastModifiedDate; import org.springframework.data.jpa.domain.AbstractPersistable; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.naturalprogrammer.spring.lemon.commons.security.PermissionEvaluatorEntity; -import com.naturalprogrammer.spring.lemon.commons.security.UserDto; - -import lombok.Getter; -import lombok.Setter; +import javax.persistence.MappedSuperclass; +import javax.persistence.Temporal; +import javax.persistence.TemporalType; +import javax.persistence.Version; +import java.io.Serializable; +import java.util.Date; /** * Base class for all entities. diff --git a/spring-lemon-commons-mongo/pom.xml b/spring-lemon-commons-mongo/pom.xml index 50cb20c6..34ffa738 100644 --- a/spring-lemon-commons-mongo/pom.xml +++ b/spring-lemon-commons-mongo/pom.xml @@ -13,7 +13,7 @@ com.naturalprogrammer spring-lemon - 1.0.0.RC3 + 1.0.0.RC4 diff --git a/spring-lemon-commons-mongo/src/main/java/com/naturalprogrammer/spring/lemon/commonsmongo/AbstractDocument.java b/spring-lemon-commons-mongo/src/main/java/com/naturalprogrammer/spring/lemon/commonsmongo/AbstractDocument.java index d939b4a5..aa8f90e6 100644 --- a/spring-lemon-commons-mongo/src/main/java/com/naturalprogrammer/spring/lemon/commonsmongo/AbstractDocument.java +++ b/spring-lemon-commons-mongo/src/main/java/com/naturalprogrammer/spring/lemon/commonsmongo/AbstractDocument.java @@ -1,21 +1,14 @@ package com.naturalprogrammer.spring.lemon.commonsmongo; -import java.io.Serializable; -import java.util.Date; - -import org.springframework.data.annotation.CreatedBy; -import org.springframework.data.annotation.CreatedDate; -import org.springframework.data.annotation.Id; -import org.springframework.data.annotation.LastModifiedBy; -import org.springframework.data.annotation.LastModifiedDate; -import org.springframework.data.annotation.Version; -import org.springframework.data.mongodb.core.mapping.Document; - import com.naturalprogrammer.spring.lemon.commons.security.PermissionEvaluatorEntity; import com.naturalprogrammer.spring.lemon.commons.security.UserDto; - import lombok.Getter; import lombok.Setter; +import org.springframework.data.annotation.*; +import org.springframework.data.mongodb.core.mapping.Document; + +import java.io.Serializable; +import java.util.Date; @Document @Getter @Setter diff --git a/spring-lemon-commons-mongo/src/main/java/com/naturalprogrammer/spring/lemon/commonsmongo/LecmUtils.java b/spring-lemon-commons-mongo/src/main/java/com/naturalprogrammer/spring/lemon/commonsmongo/LecmUtils.java index 33507b86..b473fc78 100644 --- a/spring-lemon-commons-mongo/src/main/java/com/naturalprogrammer/spring/lemon/commonsmongo/LecmUtils.java +++ b/spring-lemon-commons-mongo/src/main/java/com/naturalprogrammer/spring/lemon/commonsmongo/LecmUtils.java @@ -1,9 +1,10 @@ package com.naturalprogrammer.spring.lemon.commonsmongo; -import java.io.Serializable; - import com.naturalprogrammer.spring.lemon.exceptions.VersionException; +import java.io.Serializable; +import java.util.Objects; + public class LecmUtils { /** @@ -16,7 +17,7 @@ public class LecmUtils { public static void ensureCorrectVersion(AbstractDocument original, AbstractDocument updated) { - if (original.getVersion() != updated.getVersion()) + if (!Objects.equals(original.getVersion(), updated.getVersion())) throw new VersionException(original.getClass().getSimpleName(), original.getId().toString()); } diff --git a/spring-lemon-commons-mongo/src/main/java/com/naturalprogrammer/spring/lemon/commonsmongo/LemonCommonsMongoAutoConfiguration.java b/spring-lemon-commons-mongo/src/main/java/com/naturalprogrammer/spring/lemon/commonsmongo/LemonCommonsMongoAutoConfiguration.java index 8d57c1eb..2e83307d 100644 --- a/spring-lemon-commons-mongo/src/main/java/com/naturalprogrammer/spring/lemon/commonsmongo/LemonCommonsMongoAutoConfiguration.java +++ b/spring-lemon-commons-mongo/src/main/java/com/naturalprogrammer/spring/lemon/commonsmongo/LemonCommonsMongoAutoConfiguration.java @@ -1,12 +1,11 @@ package com.naturalprogrammer.spring.lemon.commonsmongo; +import com.naturalprogrammer.spring.lemon.commonsreactive.LemonCommonsReactiveAutoConfiguration; import org.springframework.boot.autoconfigure.AutoConfigureBefore; import org.springframework.boot.autoconfigure.mongo.MongoReactiveAutoConfiguration; import org.springframework.context.annotation.Configuration; import org.springframework.data.mongodb.config.EnableMongoAuditing; -import com.naturalprogrammer.spring.lemon.commonsreactive.LemonCommonsReactiveAutoConfiguration; - @Configuration @EnableMongoAuditing @AutoConfigureBefore({ diff --git a/spring-lemon-commons-reactive/pom.xml b/spring-lemon-commons-reactive/pom.xml index 4ad16d2b..0e65f3a9 100644 --- a/spring-lemon-commons-reactive/pom.xml +++ b/spring-lemon-commons-reactive/pom.xml @@ -13,7 +13,7 @@ com.naturalprogrammer spring-lemon - 1.0.0.RC3 + 1.0.0.RC4 diff --git a/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/LemonCommonsReactiveAutoConfiguration.java b/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/LemonCommonsReactiveAutoConfiguration.java index d3e2b769..a8094fc7 100644 --- a/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/LemonCommonsReactiveAutoConfiguration.java +++ b/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/LemonCommonsReactiveAutoConfiguration.java @@ -1,7 +1,18 @@ package com.naturalprogrammer.spring.lemon.commonsreactive; -import java.io.Serializable; - +import com.fasterxml.jackson.databind.module.SimpleModule; +import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; +import com.naturalprogrammer.spring.lemon.commons.LemonCommonsAutoConfiguration; +import com.naturalprogrammer.spring.lemon.commons.LemonProperties; +import com.naturalprogrammer.spring.lemon.commons.security.BlueTokenService; +import com.naturalprogrammer.spring.lemon.commonsreactive.exceptions.LemonReactiveErrorAttributes; +import com.naturalprogrammer.spring.lemon.commonsreactive.exceptions.handlers.VersionExceptionHandler; +import com.naturalprogrammer.spring.lemon.commonsreactive.security.LemonCommonsReactiveSecurityConfig; +import com.naturalprogrammer.spring.lemon.commonsreactive.security.LemonCorsConfigurationSource; +import com.naturalprogrammer.spring.lemon.commonsreactive.security.LemonReactiveAuditorAware; +import com.naturalprogrammer.spring.lemon.commonsreactive.util.LecrUtils; +import com.naturalprogrammer.spring.lemon.exceptions.ErrorResponseComposer; +import com.naturalprogrammer.spring.lemon.exceptions.util.LexUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.bson.types.ObjectId; @@ -23,19 +34,7 @@ import org.springframework.security.web.server.SecurityWebFilterChain; import org.springframework.web.cors.reactive.CorsConfigurationSource; -import com.fasterxml.jackson.databind.module.SimpleModule; -import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; -import com.naturalprogrammer.spring.lemon.commons.LemonCommonsAutoConfiguration; -import com.naturalprogrammer.spring.lemon.commons.LemonProperties; -import com.naturalprogrammer.spring.lemon.commons.security.BlueTokenService; -import com.naturalprogrammer.spring.lemon.commonsreactive.exceptions.LemonReactiveErrorAttributes; -import com.naturalprogrammer.spring.lemon.commonsreactive.exceptions.handlers.VersionExceptionHandler; -import com.naturalprogrammer.spring.lemon.commonsreactive.security.LemonCommonsReactiveSecurityConfig; -import com.naturalprogrammer.spring.lemon.commonsreactive.security.LemonCorsConfigurationSource; -import com.naturalprogrammer.spring.lemon.commonsreactive.security.LemonReactiveAuditorAware; -import com.naturalprogrammer.spring.lemon.commonsreactive.util.LecrUtils; -import com.naturalprogrammer.spring.lemon.exceptions.ErrorResponseComposer; -import com.naturalprogrammer.spring.lemon.exceptions.util.LexUtils; +import java.io.Serializable; @Configuration @EnableReactiveMethodSecurity diff --git a/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/exceptions/LemonReactiveErrorAttributes.java b/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/exceptions/LemonReactiveErrorAttributes.java index 6acc87a7..ea216a03 100644 --- a/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/exceptions/LemonReactiveErrorAttributes.java +++ b/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/exceptions/LemonReactiveErrorAttributes.java @@ -1,14 +1,14 @@ package com.naturalprogrammer.spring.lemon.commonsreactive.exceptions; -import java.util.Map; - +import com.naturalprogrammer.spring.lemon.exceptions.ErrorResponseComposer; +import com.naturalprogrammer.spring.lemon.exceptions.util.LexUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.springframework.boot.web.error.ErrorAttributeOptions; import org.springframework.boot.web.reactive.error.DefaultErrorAttributes; import org.springframework.web.reactive.function.server.ServerRequest; -import com.naturalprogrammer.spring.lemon.exceptions.ErrorResponseComposer; -import com.naturalprogrammer.spring.lemon.exceptions.util.LexUtils; +import java.util.Map; public class LemonReactiveErrorAttributes extends DefaultErrorAttributes { @@ -27,9 +27,9 @@ public LemonReactiveErrorAttributes(ErrorResponseComposer errorResponseCompos @Override public Map getErrorAttributes(ServerRequest request, - boolean includeStackTrace) { + ErrorAttributeOptions options) { - Map errorAttributes = super.getErrorAttributes(request, includeStackTrace); + Map errorAttributes = super.getErrorAttributes(request, options); addLemonErrorDetails(errorAttributes, request); return errorAttributes; } diff --git a/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/exceptions/handlers/VersionExceptionHandler.java b/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/exceptions/handlers/VersionExceptionHandler.java index ae68d798..837efd71 100644 --- a/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/exceptions/handlers/VersionExceptionHandler.java +++ b/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/exceptions/handlers/VersionExceptionHandler.java @@ -1,13 +1,12 @@ package com.naturalprogrammer.spring.lemon.commonsreactive.exceptions.handlers; +import com.naturalprogrammer.spring.lemon.exceptions.VersionException; +import com.naturalprogrammer.spring.lemon.exceptions.handlers.AbstractExceptionHandler; import org.springframework.core.Ordered; import org.springframework.core.annotation.Order; import org.springframework.http.HttpStatus; import org.springframework.stereotype.Component; -import com.naturalprogrammer.spring.lemon.exceptions.VersionException; -import com.naturalprogrammer.spring.lemon.exceptions.handlers.AbstractExceptionHandler; - @Component @Order(Ordered.LOWEST_PRECEDENCE) public class VersionExceptionHandler extends AbstractExceptionHandler { diff --git a/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/security/LemonCommonsReactiveSecurityConfig.java b/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/security/LemonCommonsReactiveSecurityConfig.java index 9580a012..b6ce2f95 100644 --- a/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/security/LemonCommonsReactiveSecurityConfig.java +++ b/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/security/LemonCommonsReactiveSecurityConfig.java @@ -1,5 +1,12 @@ package com.naturalprogrammer.spring.lemon.commonsreactive.security; +import com.naturalprogrammer.spring.lemon.commons.security.BlueTokenService; +import com.naturalprogrammer.spring.lemon.commons.security.LemonPrincipal; +import com.naturalprogrammer.spring.lemon.commons.security.UserDto; +import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; +import com.naturalprogrammer.spring.lemon.exceptions.util.LexUtils; +import com.nimbusds.jwt.JWTClaimsSet; +import lombok.AllArgsConstructor; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.http.HttpHeaders; @@ -8,24 +15,10 @@ import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.config.web.server.SecurityWebFiltersOrder; import org.springframework.security.config.web.server.ServerHttpSecurity; -import org.springframework.security.core.AuthenticationException; import org.springframework.security.web.server.SecurityWebFilterChain; -import org.springframework.security.web.server.ServerAuthenticationEntryPoint; -import org.springframework.security.web.server.WebFilterExchange; import org.springframework.security.web.server.authentication.AuthenticationWebFilter; import org.springframework.security.web.server.authentication.ServerAuthenticationConverter; -import org.springframework.security.web.server.authentication.ServerAuthenticationFailureHandler; -import org.springframework.security.web.server.authorization.ServerAccessDeniedHandler; import org.springframework.security.web.server.context.NoOpServerSecurityContextRepository; - -import com.naturalprogrammer.spring.lemon.commons.security.BlueTokenService; -import com.naturalprogrammer.spring.lemon.commons.security.LemonPrincipal; -import com.naturalprogrammer.spring.lemon.commons.security.UserDto; -import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; -import com.naturalprogrammer.spring.lemon.exceptions.util.LexUtils; -import com.nimbusds.jwt.JWTClaimsSet; - -import lombok.AllArgsConstructor; import reactor.core.publisher.Mono; @AllArgsConstructor diff --git a/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/security/LemonCorsConfigurationSource.java b/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/security/LemonCorsConfigurationSource.java index 3648e8ec..d4201e48 100644 --- a/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/security/LemonCorsConfigurationSource.java +++ b/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/security/LemonCorsConfigurationSource.java @@ -1,15 +1,14 @@ package com.naturalprogrammer.spring.lemon.commonsreactive.security; -import java.util.Arrays; - +import com.naturalprogrammer.spring.lemon.commons.LemonProperties; +import com.naturalprogrammer.spring.lemon.commons.LemonProperties.Cors; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.web.cors.CorsConfiguration; import org.springframework.web.cors.reactive.CorsConfigurationSource; import org.springframework.web.server.ServerWebExchange; -import com.naturalprogrammer.spring.lemon.commons.LemonProperties; -import com.naturalprogrammer.spring.lemon.commons.LemonProperties.Cors; +import java.util.Arrays; /** * CORS Configuration diff --git a/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/security/LemonReactiveAuditorAware.java b/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/security/LemonReactiveAuditorAware.java index abab5336..7284224d 100644 --- a/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/security/LemonReactiveAuditorAware.java +++ b/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/security/LemonReactiveAuditorAware.java @@ -1,12 +1,11 @@ package com.naturalprogrammer.spring.lemon.commonsreactive.security; -import java.io.Serializable; - +import com.naturalprogrammer.spring.lemon.commons.domain.AbstractAuditorAware; +import com.naturalprogrammer.spring.lemon.commons.security.UserDto; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import com.naturalprogrammer.spring.lemon.commons.domain.AbstractAuditorAware; -import com.naturalprogrammer.spring.lemon.commons.security.UserDto; +import java.io.Serializable; /** * Needed for auto-filling of the @@ -27,9 +26,12 @@ public LemonReactiveAuditorAware() { protected UserDto currentUser() { // TODO: Can't return a mono, as below + // See this: https://jira.spring.io/browse/DATACMNS-1231 // So, sorry, no reactive auditing until Spring Data supports it + // But, if using MongoDB, you could implement a ReactiveBeforeConvertCallback: + // https://juliuskrah.com/blog/2018/02/15/auditing-with-spring-data-jpa/#comment-4848839807 + // return LecrUtils.currentUser(); - return null; } } diff --git a/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/util/LecrUtils.java b/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/util/LecrUtils.java index 9af9288a..5742af65 100644 --- a/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/util/LecrUtils.java +++ b/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/util/LecrUtils.java @@ -1,24 +1,19 @@ package com.naturalprogrammer.spring.lemon.commonsreactive.util; -import java.io.IOException; -import java.io.Serializable; -import java.util.Optional; - -import javax.annotation.PostConstruct; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.springframework.http.HttpCookie; -import org.springframework.security.core.context.ReactiveSecurityContextHolder; -import org.springframework.web.server.ServerWebExchange; - import com.github.fge.jsonpatch.JsonPatchException; import com.naturalprogrammer.spring.lemon.commons.security.UserDto; import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; import com.naturalprogrammer.spring.lemon.exceptions.util.LexUtils; - +import org.springframework.http.HttpCookie; +import org.springframework.security.core.context.ReactiveSecurityContextHolder; +import org.springframework.web.server.ServerWebExchange; import reactor.core.publisher.Mono; +import javax.annotation.PostConstruct; +import java.io.IOException; +import java.io.Serializable; +import java.util.Optional; + /** * Useful helper methods * @@ -26,8 +21,6 @@ */ public class LecrUtils { - private static final Log log = LogFactory.getLog(LecrUtils.class); - private static Mono NOT_FOUND_MONO; @PostConstruct @@ -46,7 +39,7 @@ public static Mono> currentUser() { return ReactiveSecurityContextHolder.getContext() .map(LecUtils::currentUser) - .map(user -> Optional.of(user)) + .map(Optional::of) .defaultIfEmpty(Optional.empty()); } diff --git a/spring-lemon-commons-web/pom.xml b/spring-lemon-commons-web/pom.xml index 1ec0c889..f7d37066 100644 --- a/spring-lemon-commons-web/pom.xml +++ b/spring-lemon-commons-web/pom.xml @@ -13,7 +13,7 @@ com.naturalprogrammer spring-lemon - 1.0.0.RC3 + 1.0.0.RC4 diff --git a/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/LemonCommonsWebAutoConfiguration.java b/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/LemonCommonsWebAutoConfiguration.java index f5f45cb7..6dbd02ca 100644 --- a/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/LemonCommonsWebAutoConfiguration.java +++ b/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/LemonCommonsWebAutoConfiguration.java @@ -1,8 +1,16 @@ package com.naturalprogrammer.spring.lemon.commonsweb; -import java.io.Serializable; -import java.util.List; - +import com.fasterxml.jackson.databind.ObjectMapper; +import com.naturalprogrammer.spring.lemon.commons.LemonCommonsAutoConfiguration; +import com.naturalprogrammer.spring.lemon.commons.LemonProperties; +import com.naturalprogrammer.spring.lemon.commonsweb.exceptions.DefaultExceptionHandlerControllerAdvice; +import com.naturalprogrammer.spring.lemon.commonsweb.exceptions.LemonErrorAttributes; +import com.naturalprogrammer.spring.lemon.commonsweb.exceptions.LemonErrorController; +import com.naturalprogrammer.spring.lemon.commonsweb.security.LemonCorsConfigurationSource; +import com.naturalprogrammer.spring.lemon.commonsweb.security.LemonWebAuditorAware; +import com.naturalprogrammer.spring.lemon.commonsweb.security.LemonWebSecurityConfig; +import com.naturalprogrammer.spring.lemon.commonsweb.util.LecwUtils; +import com.naturalprogrammer.spring.lemon.exceptions.ErrorResponseComposer; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.boot.autoconfigure.AutoConfigureBefore; @@ -25,17 +33,8 @@ import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; import org.springframework.web.cors.CorsConfigurationSource; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.naturalprogrammer.spring.lemon.commons.LemonCommonsAutoConfiguration; -import com.naturalprogrammer.spring.lemon.commons.LemonProperties; -import com.naturalprogrammer.spring.lemon.commonsweb.exceptions.DefaultExceptionHandlerControllerAdvice; -import com.naturalprogrammer.spring.lemon.commonsweb.exceptions.LemonErrorAttributes; -import com.naturalprogrammer.spring.lemon.commonsweb.exceptions.LemonErrorController; -import com.naturalprogrammer.spring.lemon.commonsweb.security.LemonCorsConfigurationSource; -import com.naturalprogrammer.spring.lemon.commonsweb.security.LemonWebAuditorAware; -import com.naturalprogrammer.spring.lemon.commonsweb.security.LemonWebSecurityConfig; -import com.naturalprogrammer.spring.lemon.commonsweb.util.LecwUtils; -import com.naturalprogrammer.spring.lemon.exceptions.ErrorResponseComposer; +import java.io.Serializable; +import java.util.List; @Configuration @EnableSpringDataWebSupport @@ -53,7 +52,7 @@ public class LemonCommonsWebAutoConfiguration { * JSON response bodies would be prefixed with * this string. */ - public final static String JSON_PREFIX = ")]}',\n"; + public static final String JSON_PREFIX = ")]}',\n"; private static final Log log = LogFactory.getLog(LemonCommonsWebAutoConfiguration.class); diff --git a/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/exceptions/DefaultExceptionHandlerControllerAdvice.java b/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/exceptions/DefaultExceptionHandlerControllerAdvice.java index 250912fa..89b2c03e 100644 --- a/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/exceptions/DefaultExceptionHandlerControllerAdvice.java +++ b/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/exceptions/DefaultExceptionHandlerControllerAdvice.java @@ -1,5 +1,7 @@ package com.naturalprogrammer.spring.lemon.commonsweb.exceptions; +import com.naturalprogrammer.spring.lemon.exceptions.ErrorResponse; +import com.naturalprogrammer.spring.lemon.exceptions.ErrorResponseComposer; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.http.HttpStatus; @@ -8,9 +10,6 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestControllerAdvice; -import com.naturalprogrammer.spring.lemon.exceptions.ErrorResponse; -import com.naturalprogrammer.spring.lemon.exceptions.ErrorResponseComposer; - /** * Handles exceptions thrown from in controllers or inner routines */ diff --git a/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/exceptions/LemonErrorAttributes.java b/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/exceptions/LemonErrorAttributes.java index 4c85d3f7..788d58df 100644 --- a/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/exceptions/LemonErrorAttributes.java +++ b/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/exceptions/LemonErrorAttributes.java @@ -1,14 +1,14 @@ package com.naturalprogrammer.spring.lemon.commonsweb.exceptions; -import java.util.Map; - +import com.naturalprogrammer.spring.lemon.exceptions.ErrorResponseComposer; +import com.naturalprogrammer.spring.lemon.exceptions.util.LexUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.springframework.boot.web.error.ErrorAttributeOptions; import org.springframework.boot.web.servlet.error.DefaultErrorAttributes; import org.springframework.web.context.request.WebRequest; -import com.naturalprogrammer.spring.lemon.exceptions.ErrorResponseComposer; -import com.naturalprogrammer.spring.lemon.exceptions.util.LexUtils; +import java.util.Map; /** * Used for handling exceptions that can't be handled by @@ -34,10 +34,10 @@ public LemonErrorAttributes(ErrorResponseComposer errorResponseComposer) { */ @Override public Map getErrorAttributes(WebRequest request, - boolean includeStackTrace) { + ErrorAttributeOptions options) { Map errorAttributes = - super.getErrorAttributes(request, includeStackTrace); + super.getErrorAttributes(request, options); addLemonErrorDetails(errorAttributes, request); diff --git a/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/exceptions/LemonErrorController.java b/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/exceptions/LemonErrorController.java index 9894044c..4ccf5ba5 100644 --- a/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/exceptions/LemonErrorController.java +++ b/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/exceptions/LemonErrorController.java @@ -1,10 +1,5 @@ package com.naturalprogrammer.spring.lemon.commonsweb.exceptions; -import java.util.List; -import java.util.Map; - -import javax.servlet.http.HttpServletRequest; - import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.boot.autoconfigure.web.ServerProperties; @@ -16,6 +11,10 @@ import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; +import javax.servlet.http.HttpServletRequest; +import java.util.List; +import java.util.Map; + /** * Used for handling exceptions that can't be handled by * DefaultExceptionHandlerControllerAdvice, @@ -40,7 +39,7 @@ public LemonErrorController(ErrorAttributes errorAttributes, public ResponseEntity> error(HttpServletRequest request) { Map body = getErrorAttributes(request, - isIncludeStackTrace(request, MediaType.ALL)); + getErrorAttributeOptions(request, MediaType.ALL)); // if a status was put in LemonErrorAttributes, fetch that Object statusObj = body.get(LemonErrorAttributes.HTTP_STATUS_KEY); @@ -54,8 +53,8 @@ public ResponseEntity> error(HttpServletRequest request) { body.remove(LemonErrorAttributes.HTTP_STATUS_KEY); // clean the status from the map } HttpHeaders headers = new HttpHeaders(); - headers.setContentType(MediaType.APPLICATION_JSON_UTF8); + headers.setContentType(MediaType.APPLICATION_JSON); - return new ResponseEntity>(body, headers, status); + return new ResponseEntity<>(body, headers, status); } } diff --git a/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/security/LemonCommonsWebTokenAuthenticationFilter.java b/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/security/LemonCommonsWebTokenAuthenticationFilter.java index 7b14c69b..d92b3c2f 100644 --- a/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/security/LemonCommonsWebTokenAuthenticationFilter.java +++ b/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/security/LemonCommonsWebTokenAuthenticationFilter.java @@ -1,12 +1,12 @@ package com.naturalprogrammer.spring.lemon.commonsweb.security; -import java.io.IOException; - -import javax.servlet.FilterChain; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - +import com.naturalprogrammer.spring.lemon.commons.security.BlueTokenService; +import com.naturalprogrammer.spring.lemon.commons.security.LemonPrincipal; +import com.naturalprogrammer.spring.lemon.commons.security.UserDto; +import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; +import com.naturalprogrammer.spring.lemon.exceptions.util.LexUtils; +import com.nimbusds.jwt.JWTClaimsSet; +import lombok.AllArgsConstructor; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.http.HttpHeaders; @@ -16,14 +16,11 @@ import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.web.filter.OncePerRequestFilter; -import com.naturalprogrammer.spring.lemon.commons.security.BlueTokenService; -import com.naturalprogrammer.spring.lemon.commons.security.LemonPrincipal; -import com.naturalprogrammer.spring.lemon.commons.security.UserDto; -import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; -import com.naturalprogrammer.spring.lemon.exceptions.util.LexUtils; -import com.nimbusds.jwt.JWTClaimsSet; - -import lombok.AllArgsConstructor; +import javax.servlet.FilterChain; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; /** * Filter for token authentication diff --git a/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/security/LemonCorsConfigurationSource.java b/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/security/LemonCorsConfigurationSource.java index 3ea37cab..d98ca834 100644 --- a/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/security/LemonCorsConfigurationSource.java +++ b/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/security/LemonCorsConfigurationSource.java @@ -1,16 +1,14 @@ package com.naturalprogrammer.spring.lemon.commonsweb.security; -import java.util.Arrays; - -import javax.servlet.http.HttpServletRequest; - +import com.naturalprogrammer.spring.lemon.commons.LemonProperties; +import com.naturalprogrammer.spring.lemon.commons.LemonProperties.Cors; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.web.cors.CorsConfiguration; import org.springframework.web.cors.CorsConfigurationSource; -import com.naturalprogrammer.spring.lemon.commons.LemonProperties; -import com.naturalprogrammer.spring.lemon.commons.LemonProperties.Cors; +import javax.servlet.http.HttpServletRequest; +import java.util.Arrays; /** * CORS Configuration diff --git a/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/security/LemonWebAuditorAware.java b/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/security/LemonWebAuditorAware.java index 864ee0fb..c06bdfa9 100644 --- a/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/security/LemonWebAuditorAware.java +++ b/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/security/LemonWebAuditorAware.java @@ -1,13 +1,12 @@ package com.naturalprogrammer.spring.lemon.commonsweb.security; -import java.io.Serializable; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - import com.naturalprogrammer.spring.lemon.commons.domain.AbstractAuditorAware; import com.naturalprogrammer.spring.lemon.commons.security.UserDto; import com.naturalprogrammer.spring.lemon.commonsweb.util.LecwUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import java.io.Serializable; /** * Needed for auto-filling of the diff --git a/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/security/LemonWebSecurityConfig.java b/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/security/LemonWebSecurityConfig.java index 2b9c9f26..1ccce3e2 100644 --- a/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/security/LemonWebSecurityConfig.java +++ b/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/security/LemonWebSecurityConfig.java @@ -1,5 +1,6 @@ package com.naturalprogrammer.spring.lemon.commonsweb.security; +import com.naturalprogrammer.spring.lemon.commons.security.BlueTokenService; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -9,8 +10,6 @@ import org.springframework.security.web.authentication.Http403ForbiddenEntryPoint; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; -import com.naturalprogrammer.spring.lemon.commons.security.BlueTokenService; - /** * Security configuration class. Extend it in the * application, and make a configuration class. Override @@ -88,7 +87,7 @@ protected void exceptionHandling(HttpSecurity http) throws Exception { /** * Configuring token authentication filter */ - protected void tokenAuthentication(HttpSecurity http) throws Exception { + protected void tokenAuthentication(HttpSecurity http) { http.addFilterBefore(new LemonCommonsWebTokenAuthenticationFilter(blueTokenService), UsernamePasswordAuthenticationFilter.class); diff --git a/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/util/LecwUtils.java b/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/util/LecwUtils.java index 9635a192..767178ec 100644 --- a/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/util/LecwUtils.java +++ b/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/util/LecwUtils.java @@ -1,16 +1,14 @@ package com.naturalprogrammer.spring.lemon.commonsweb.util; -import java.util.Optional; - -import javax.servlet.http.Cookie; -import javax.servlet.http.HttpServletRequest; - +import com.naturalprogrammer.spring.lemon.commons.security.UserDto; +import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.security.core.context.SecurityContextHolder; -import com.naturalprogrammer.spring.lemon.commons.security.UserDto; -import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; +import javax.servlet.http.Cookie; +import javax.servlet.http.HttpServletRequest; +import java.util.Optional; public class LecwUtils { diff --git a/spring-lemon-commons/pom.xml b/spring-lemon-commons/pom.xml index ba829f92..bfcb03c8 100644 --- a/spring-lemon-commons/pom.xml +++ b/spring-lemon-commons/pom.xml @@ -14,7 +14,7 @@ com.naturalprogrammer spring-lemon - 1.0.0.RC3 + 1.0.0.RC4 diff --git a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/AbstractLemonService.java b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/AbstractLemonService.java index fb2149ab..526864ed 100644 --- a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/AbstractLemonService.java +++ b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/AbstractLemonService.java @@ -1,17 +1,5 @@ package com.naturalprogrammer.spring.lemon.commons; -import java.io.Serializable; -import java.util.HashMap; -import java.util.Map; - -import org.apache.commons.lang3.exception.ExceptionUtils; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.springframework.boot.context.event.ApplicationReadyEvent; -import org.springframework.context.event.EventListener; -import org.springframework.security.crypto.password.PasswordEncoder; -import org.springframework.security.oauth2.core.oidc.StandardClaimNames; - import com.naturalprogrammer.spring.lemon.commons.LemonProperties.Admin; import com.naturalprogrammer.spring.lemon.commons.domain.LemonUser; import com.naturalprogrammer.spring.lemon.commons.mail.LemonMailData; @@ -21,6 +9,17 @@ import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; import com.naturalprogrammer.spring.lemon.commons.util.UserUtils; import com.naturalprogrammer.spring.lemon.exceptions.util.LexUtils; +import org.apache.commons.lang3.exception.ExceptionUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.springframework.boot.context.event.ApplicationReadyEvent; +import org.springframework.context.event.EventListener; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.security.oauth2.core.oidc.StandardClaimNames; + +import java.io.Serializable; +import java.util.HashMap; +import java.util.Map; public abstract class AbstractLemonService , ID extends Serializable> { @@ -74,7 +73,7 @@ protected U createAdminUser() { protected Map buildContext() { // make the context - Map sharedProperties = new HashMap(2); + Map sharedProperties = new HashMap<>(2); sharedProperties.put("reCaptchaSiteKey", properties.getRecaptcha().getSitekey()); sharedProperties.put("shared", properties.getShared()); @@ -122,7 +121,7 @@ protected void sendVerificationMail(final U user) { log.debug("Verification mail to " + user.getEmail() + " queued."); - } catch (Throwable e) { + } catch (Exception e) { // In case of exception, just log the error and keep silent log.error(ExceptionUtils.getStackTrace(e)); } @@ -213,7 +212,7 @@ public boolean getOAuth2AccountVerified(String registrationId, Map { diff --git a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/exceptions/handlers/BadCredentialsExceptionHandler.java b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/exceptions/handlers/BadCredentialsExceptionHandler.java index cdb04bec..554934a7 100644 --- a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/exceptions/handlers/BadCredentialsExceptionHandler.java +++ b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/exceptions/handlers/BadCredentialsExceptionHandler.java @@ -1,13 +1,12 @@ package com.naturalprogrammer.spring.lemon.commons.exceptions.handlers; +import com.naturalprogrammer.spring.lemon.exceptions.handlers.AbstractExceptionHandler; import org.springframework.core.Ordered; import org.springframework.core.annotation.Order; import org.springframework.http.HttpStatus; import org.springframework.security.authentication.BadCredentialsException; import org.springframework.stereotype.Component; -import com.naturalprogrammer.spring.lemon.exceptions.handlers.AbstractExceptionHandler; - @Component @Order(Ordered.LOWEST_PRECEDENCE) public class BadCredentialsExceptionHandler extends AbstractExceptionHandler { diff --git a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/exceptions/handlers/JsonParseExceptionHandler.java b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/exceptions/handlers/JsonParseExceptionHandler.java index 73a35651..5ba00886 100644 --- a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/exceptions/handlers/JsonParseExceptionHandler.java +++ b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/exceptions/handlers/JsonParseExceptionHandler.java @@ -1,12 +1,11 @@ package com.naturalprogrammer.spring.lemon.commons.exceptions.handlers; +import com.fasterxml.jackson.core.JsonParseException; +import com.naturalprogrammer.spring.lemon.exceptions.handlers.AbstractBadRequestExceptionHandler; import org.springframework.core.Ordered; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; -import com.fasterxml.jackson.core.JsonParseException; -import com.naturalprogrammer.spring.lemon.exceptions.handlers.AbstractBadRequestExceptionHandler; - @Component @Order(Ordered.LOWEST_PRECEDENCE) public class JsonParseExceptionHandler extends AbstractBadRequestExceptionHandler { diff --git a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/exceptions/handlers/JsonPatchExceptionHandler.java b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/exceptions/handlers/JsonPatchExceptionHandler.java index 33479db9..4b6f0989 100644 --- a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/exceptions/handlers/JsonPatchExceptionHandler.java +++ b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/exceptions/handlers/JsonPatchExceptionHandler.java @@ -1,12 +1,11 @@ package com.naturalprogrammer.spring.lemon.commons.exceptions.handlers; +import com.github.fge.jsonpatch.JsonPatchException; +import com.naturalprogrammer.spring.lemon.exceptions.handlers.AbstractBadRequestExceptionHandler; import org.springframework.core.Ordered; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; -import com.github.fge.jsonpatch.JsonPatchException; -import com.naturalprogrammer.spring.lemon.exceptions.handlers.AbstractBadRequestExceptionHandler; - @Component @Order(Ordered.LOWEST_PRECEDENCE) public class JsonPatchExceptionHandler extends AbstractBadRequestExceptionHandler { diff --git a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/exceptions/handlers/JsonProcessingExceptionHandler.java b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/exceptions/handlers/JsonProcessingExceptionHandler.java index d49d34f6..034ae770 100644 --- a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/exceptions/handlers/JsonProcessingExceptionHandler.java +++ b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/exceptions/handlers/JsonProcessingExceptionHandler.java @@ -1,12 +1,11 @@ package com.naturalprogrammer.spring.lemon.commons.exceptions.handlers; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.naturalprogrammer.spring.lemon.exceptions.handlers.AbstractBadRequestExceptionHandler; import org.springframework.core.Ordered; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.naturalprogrammer.spring.lemon.exceptions.handlers.AbstractBadRequestExceptionHandler; - @Component @Order(Ordered.LOWEST_PRECEDENCE) public class JsonProcessingExceptionHandler extends AbstractBadRequestExceptionHandler { diff --git a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/exceptions/handlers/UsernameNotFoundExceptionHandler.java b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/exceptions/handlers/UsernameNotFoundExceptionHandler.java index f2d14e10..78a70c40 100644 --- a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/exceptions/handlers/UsernameNotFoundExceptionHandler.java +++ b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/exceptions/handlers/UsernameNotFoundExceptionHandler.java @@ -1,13 +1,12 @@ package com.naturalprogrammer.spring.lemon.commons.exceptions.handlers; +import com.naturalprogrammer.spring.lemon.exceptions.handlers.AbstractExceptionHandler; import org.springframework.core.Ordered; import org.springframework.core.annotation.Order; import org.springframework.http.HttpStatus; import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.stereotype.Component; -import com.naturalprogrammer.spring.lemon.exceptions.handlers.AbstractExceptionHandler; - @Component @Order(Ordered.LOWEST_PRECEDENCE) public class UsernameNotFoundExceptionHandler extends AbstractExceptionHandler { diff --git a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/mail/SmtpMailSender.java b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/mail/SmtpMailSender.java index e0ab00c1..557b2ffe 100644 --- a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/mail/SmtpMailSender.java +++ b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/mail/SmtpMailSender.java @@ -1,14 +1,14 @@ package com.naturalprogrammer.spring.lemon.commons.mail; -import javax.mail.MessagingException; -import javax.mail.internet.MimeMessage; - import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.mail.javamail.JavaMailSender; import org.springframework.mail.javamail.MimeMessageHelper; import org.springframework.scheduling.annotation.Async; +import javax.mail.MessagingException; +import javax.mail.internet.MimeMessage; + /** * An SMTP mail sender, which sends mails diff --git a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/AbstractJwtService.java b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/AbstractJwtService.java index d3430b3d..5afe0ee4 100644 --- a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/AbstractJwtService.java +++ b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/AbstractJwtService.java @@ -1,15 +1,14 @@ package com.naturalprogrammer.spring.lemon.commons.security; -import java.util.Date; -import java.util.HashMap; -import java.util.Map; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; import com.nimbusds.jose.Payload; import com.nimbusds.jwt.JWTClaimsSet; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import java.util.Date; +import java.util.HashMap; +import java.util.Map; /** * Common JWT Service diff --git a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/LemonGrantedAuthority.java b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/LemonGrantedAuthority.java index 7b3dd0a4..f5a47fad 100644 --- a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/LemonGrantedAuthority.java +++ b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/LemonGrantedAuthority.java @@ -1,10 +1,9 @@ package com.naturalprogrammer.spring.lemon.commons.security; -import org.springframework.security.core.GrantedAuthority; - import lombok.AllArgsConstructor; import lombok.Getter; import lombok.Setter; +import org.springframework.security.core.GrantedAuthority; /** * Our implementation of GrantedAuthority. diff --git a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/LemonJweService.java b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/LemonJweService.java index 2fa730ef..bf2a6a86 100644 --- a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/LemonJweService.java +++ b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/LemonJweService.java @@ -1,19 +1,6 @@ package com.naturalprogrammer.spring.lemon.commons.security; -import java.text.ParseException; -import java.util.Map; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.springframework.security.authentication.BadCredentialsException; - -import com.nimbusds.jose.EncryptionMethod; -import com.nimbusds.jose.JOSEException; -import com.nimbusds.jose.JWEAlgorithm; -import com.nimbusds.jose.JWEHeader; -import com.nimbusds.jose.JWEObject; -import com.nimbusds.jose.KeyLengthException; -import com.nimbusds.jose.Payload; +import com.nimbusds.jose.*; import com.nimbusds.jose.crypto.DirectEncrypter; import com.nimbusds.jose.jwk.source.ImmutableSecret; import com.nimbusds.jose.jwk.source.JWKSource; @@ -24,6 +11,10 @@ import com.nimbusds.jwt.JWTClaimsSet; import com.nimbusds.jwt.proc.ConfigurableJWTProcessor; import com.nimbusds.jwt.proc.DefaultJWTProcessor; +import org.springframework.security.authentication.BadCredentialsException; + +import java.text.ParseException; +import java.util.Map; /** * JWE Service @@ -35,8 +26,6 @@ */ public class LemonJweService extends AbstractJwtService implements GreenTokenService { - private static final Log log = LogFactory.getLog(LemonJweService.class); - private DirectEncrypter encrypter; private JWEHeader header = new JWEHeader(JWEAlgorithm.DIR, EncryptionMethod.A128CBC_HS256); private ConfigurableJWTProcessor jwtProcessor; diff --git a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/LemonJwsService.java b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/LemonJwsService.java index 1c5a80b8..82ad1957 100644 --- a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/LemonJwsService.java +++ b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/LemonJwsService.java @@ -1,20 +1,13 @@ package com.naturalprogrammer.spring.lemon.commons.security; -import java.text.ParseException; -import java.util.Map; - -import org.springframework.security.authentication.BadCredentialsException; - -import com.nimbusds.jose.JOSEException; -import com.nimbusds.jose.JWSAlgorithm; -import com.nimbusds.jose.JWSHeader; -import com.nimbusds.jose.JWSObject; -import com.nimbusds.jose.JWSSigner; -import com.nimbusds.jose.JWSVerifier; -import com.nimbusds.jose.Payload; +import com.nimbusds.jose.*; import com.nimbusds.jose.crypto.MACSigner; import com.nimbusds.jose.crypto.MACVerifier; import com.nimbusds.jwt.JWTClaimsSet; +import org.springframework.security.authentication.BadCredentialsException; + +import java.text.ParseException; +import java.util.Map; /** * JWS Service @@ -28,7 +21,6 @@ public class LemonJwsService extends AbstractJwtService implements BlueTokenServ public LemonJwsService(String secret) throws JOSEException { - byte[] secretKey = secret.getBytes(); signer = new MACSigner(secret); verifier = new MACVerifier(secret); } diff --git a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/LemonPermissionEvaluator.java b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/LemonPermissionEvaluator.java index fc5726bb..9063b9b9 100644 --- a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/LemonPermissionEvaluator.java +++ b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/LemonPermissionEvaluator.java @@ -1,13 +1,12 @@ package com.naturalprogrammer.spring.lemon.commons.security; -import java.io.Serializable; - +import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.security.access.PermissionEvaluator; import org.springframework.security.core.Authentication; -import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; +import java.io.Serializable; /** * Needed to check the permission for the service methods diff --git a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/LemonPrincipal.java b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/LemonPrincipal.java index a2933850..e8fa2d3b 100644 --- a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/LemonPrincipal.java +++ b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/LemonPrincipal.java @@ -1,11 +1,10 @@ package com.naturalprogrammer.spring.lemon.commons.security; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Map; -import java.util.Set; -import java.util.stream.Collectors; - +import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import lombok.Setter; import org.springframework.security.core.CredentialsContainer; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.userdetails.UserDetails; @@ -13,12 +12,11 @@ import org.springframework.security.oauth2.core.oidc.OidcUserInfo; import org.springframework.security.oauth2.core.oidc.user.OidcUser; -import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; - -import lombok.AccessLevel; -import lombok.Getter; -import lombok.RequiredArgsConstructor; -import lombok.Setter; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; /** * Spring Security Principal, implementing both OidcUser, UserDetails diff --git a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/LemonTokenService.java b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/LemonTokenService.java index 99c7c6b1..14ee600c 100644 --- a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/LemonTokenService.java +++ b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/LemonTokenService.java @@ -1,9 +1,9 @@ package com.naturalprogrammer.spring.lemon.commons.security; -import java.util.Map; - import com.nimbusds.jwt.JWTClaimsSet; +import java.util.Map; + public interface LemonTokenService { String LEMON_IAT = "lemon-iat"; diff --git a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/UserDto.java b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/UserDto.java index f2825e27..65d1cf68 100644 --- a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/UserDto.java +++ b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/UserDto.java @@ -1,15 +1,14 @@ package com.naturalprogrammer.spring.lemon.commons.security; -import java.io.Serializable; -import java.util.HashSet; -import java.util.Set; - import com.naturalprogrammer.spring.lemon.commons.util.UserUtils; - import lombok.Getter; import lombok.Setter; import lombok.ToString; +import java.io.Serializable; +import java.util.HashSet; +import java.util.Set; + /** * A lighter User class, * mainly used for holding logged-in user data @@ -22,7 +21,7 @@ public class UserDto implements Serializable { private String id; private String username; private String password; - private Set roles = new HashSet(); + private Set roles = new HashSet<>(); private Serializable tag; private boolean unverified = false; diff --git a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/UserEditPermission.java b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/UserEditPermission.java index 36c05eb3..ca0cac71 100644 --- a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/UserEditPermission.java +++ b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/UserEditPermission.java @@ -1,10 +1,10 @@ package com.naturalprogrammer.spring.lemon.commons.security; +import org.springframework.security.access.prepost.PreAuthorize; + import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; -import org.springframework.security.access.prepost.PreAuthorize; - @Retention(RetentionPolicy.RUNTIME) @PreAuthorize("hasPermission(#user, 'edit')") public @interface UserEditPermission {} \ No newline at end of file diff --git a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/util/LecUtils.java b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/util/LecUtils.java index a75c56b7..e2075267 100644 --- a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/util/LecUtils.java +++ b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/util/LecUtils.java @@ -1,24 +1,5 @@ package com.naturalprogrammer.spring.lemon.commons.util; -import java.io.IOException; -import java.io.Serializable; -import java.nio.charset.StandardCharsets; -import java.util.Base64; -import java.util.HashMap; -import java.util.Map; -import java.util.Scanner; -import java.util.UUID; - -import org.apache.commons.lang3.SerializationUtils; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.springframework.context.ApplicationContext; -import org.springframework.core.io.Resource; -import org.springframework.security.access.AccessDeniedException; -import org.springframework.security.authentication.BadCredentialsException; -import org.springframework.security.core.Authentication; -import org.springframework.security.core.context.SecurityContext; - import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.TreeNode; import com.fasterxml.jackson.databind.JsonNode; @@ -30,6 +11,20 @@ import com.naturalprogrammer.spring.lemon.commons.security.UserDto; import com.naturalprogrammer.spring.lemon.exceptions.util.LexUtils; import com.nimbusds.jwt.JWTClaimsSet; +import org.apache.commons.lang3.SerializationUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.springframework.context.ApplicationContext; +import org.springframework.core.io.Resource; +import org.springframework.security.access.AccessDeniedException; +import org.springframework.security.authentication.BadCredentialsException; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContext; + +import java.io.IOException; +import java.io.Serializable; +import java.nio.charset.StandardCharsets; +import java.util.*; /** * Useful helper methods diff --git a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/util/UserUtils.java b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/util/UserUtils.java index e32a60a6..43e2bd65 100644 --- a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/util/UserUtils.java +++ b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/util/UserUtils.java @@ -1,10 +1,9 @@ package com.naturalprogrammer.spring.lemon.commons.util; +import com.naturalprogrammer.spring.lemon.commons.security.UserDto; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import com.naturalprogrammer.spring.lemon.commons.security.UserDto; - public class UserUtils { private static final Log log = LogFactory.getLog(UserUtils.class); diff --git a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/validation/Captcha.java b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/validation/Captcha.java index df325703..17e637fa 100644 --- a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/validation/Captcha.java +++ b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/validation/Captcha.java @@ -1,10 +1,9 @@ package com.naturalprogrammer.spring.lemon.commons.validation; +import javax.validation.Constraint; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; -import javax.validation.Constraint; - /** * Captcha validation constraint annotation * diff --git a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/validation/CaptchaValidator.java b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/validation/CaptchaValidator.java index 00876edb..dc29deb4 100644 --- a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/validation/CaptchaValidator.java +++ b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/validation/CaptchaValidator.java @@ -1,10 +1,7 @@ package com.naturalprogrammer.spring.lemon.commons.validation; -import java.util.Collection; - -import javax.validation.ConstraintValidator; -import javax.validation.ConstraintValidatorContext; - +import com.fasterxml.jackson.annotation.JsonProperty; +import com.naturalprogrammer.spring.lemon.commons.LemonProperties; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.exception.ExceptionUtils; import org.apache.commons.logging.Log; @@ -13,8 +10,9 @@ import org.springframework.util.MultiValueMap; import org.springframework.web.client.RestTemplate; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.naturalprogrammer.spring.lemon.commons.LemonProperties; +import javax.validation.ConstraintValidator; +import javax.validation.ConstraintValidatorContext; +import java.util.Collection; /** * Captcha validation constraint @@ -89,8 +87,7 @@ public boolean isValid(String captchaResponse, ConstraintValidatorContext contex return false; // Prepare the form data for sending to google - MultiValueMap formData = - new LinkedMultiValueMap(2); + MultiValueMap formData = new LinkedMultiValueMap<>(2); formData.add("response", captchaResponse); formData.add("secret", properties.getRecaptcha().getSecretkey()); @@ -114,8 +111,8 @@ public boolean isValid(String captchaResponse, ConstraintValidatorContext contex log.info("Captcha validation failed."); return false; - } catch (Throwable t) { - log.error(ExceptionUtils.getStackTrace(t)); + } catch (Exception e) { + log.error(ExceptionUtils.getStackTrace(e)); return false; } } diff --git a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/validation/Password.java b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/validation/Password.java index 04cea093..bf94c676 100644 --- a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/validation/Password.java +++ b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/validation/Password.java @@ -1,15 +1,14 @@ package com.naturalprogrammer.spring.lemon.commons.validation; -import static java.lang.annotation.RetentionPolicy.RUNTIME; - -import java.lang.annotation.Retention; +import com.naturalprogrammer.spring.lemon.commons.util.UserUtils; import javax.validation.Constraint; import javax.validation.Payload; import javax.validation.constraints.NotBlank; import javax.validation.constraints.Size; +import java.lang.annotation.Retention; -import com.naturalprogrammer.spring.lemon.commons.util.UserUtils; +import static java.lang.annotation.RetentionPolicy.RUNTIME; /** * Annotation for password constraint diff --git a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/validation/RetypePassword.java b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/validation/RetypePassword.java index bd98e3c9..171ab268 100644 --- a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/validation/RetypePassword.java +++ b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/validation/RetypePassword.java @@ -1,10 +1,9 @@ package com.naturalprogrammer.spring.lemon.commons.validation; +import javax.validation.Constraint; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; -import javax.validation.Constraint; - /** * Annotation for retype password constraint * diff --git a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/validation/RetypePasswordValidator.java b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/validation/RetypePasswordValidator.java index 7e89db99..367cbad6 100644 --- a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/validation/RetypePasswordValidator.java +++ b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/validation/RetypePasswordValidator.java @@ -1,12 +1,11 @@ package com.naturalprogrammer.spring.lemon.commons.validation; -import java.util.Objects; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; import javax.validation.ConstraintValidator; import javax.validation.ConstraintValidatorContext; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; +import java.util.Objects; /** * Validator for RetypePassword constraint diff --git a/spring-lemon-commons/src/test/java/com/naturalprogrammer/spring/lemon/commons/security/LemonJwtServiceTests.java b/spring-lemon-commons/src/test/java/com/naturalprogrammer/spring/lemon/commons/security/LemonJwtServiceTests.java index dbb22cb2..b0933413 100644 --- a/spring-lemon-commons/src/test/java/com/naturalprogrammer/spring/lemon/commons/security/LemonJwtServiceTests.java +++ b/spring-lemon-commons/src/test/java/com/naturalprogrammer/spring/lemon/commons/security/LemonJwtServiceTests.java @@ -1,15 +1,14 @@ package com.naturalprogrammer.spring.lemon.commons.security; +import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; +import com.nimbusds.jose.JOSEException; +import com.nimbusds.jwt.JWTClaimsSet; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.junit.Assert; import org.junit.Test; import org.springframework.security.authentication.BadCredentialsException; -import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; -import com.nimbusds.jose.JOSEException; -import com.nimbusds.jwt.JWTClaimsSet; - public class LemonJwtServiceTests { private static final Log log = LogFactory.getLog(LemonJwtServiceTests.class); diff --git a/spring-lemon-exceptions/pom.xml b/spring-lemon-exceptions/pom.xml index d394c6f8..9250d34c 100644 --- a/spring-lemon-exceptions/pom.xml +++ b/spring-lemon-exceptions/pom.xml @@ -13,7 +13,7 @@ com.naturalprogrammer spring-lemon - 1.0.0.RC3 + 1.0.0.RC4 diff --git a/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/ErrorResponse.java b/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/ErrorResponse.java index 6063e225..210eaf14 100644 --- a/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/ErrorResponse.java +++ b/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/ErrorResponse.java @@ -1,10 +1,10 @@ package com.naturalprogrammer.spring.lemon.exceptions; -import java.util.Collection; - import lombok.Getter; import lombok.Setter; +import java.util.Collection; + /** * Error DTO, to be sent as response body * in case of errors diff --git a/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/ErrorResponseComposer.java b/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/ErrorResponseComposer.java index ef73cd07..f3946302 100644 --- a/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/ErrorResponseComposer.java +++ b/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/ErrorResponseComposer.java @@ -1,17 +1,16 @@ package com.naturalprogrammer.spring.lemon.exceptions; +import com.naturalprogrammer.spring.lemon.exceptions.handlers.AbstractExceptionHandler; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.springframework.core.annotation.AnnotationAwareOrderComparator; + import java.util.List; import java.util.Map; import java.util.Optional; import java.util.function.Function; import java.util.stream.Collectors; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.springframework.core.annotation.AnnotationAwareOrderComparator; - -import com.naturalprogrammer.spring.lemon.exceptions.handlers.AbstractExceptionHandler; - /** * Given an exception, builds a response. */ @@ -25,12 +24,12 @@ public ErrorResponseComposer(List> handlers) { this.handlers = handlers.stream().collect( Collectors.toMap(AbstractExceptionHandler::getExceptionClass, - Function.identity(), (handler1, handler2) -> { + Function.identity(), (handler1, handler2) -> - return AnnotationAwareOrderComparator - .INSTANCE.compare(handler1, handler2) < 0 ? - handler1 : handler2; - })); + AnnotationAwareOrderComparator + .INSTANCE.compare(handler1, handler2) < 0 ? + handler1 : handler2 + )); log.info("Created"); } diff --git a/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/LemonExceptionsAutoConfiguration.java b/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/LemonExceptionsAutoConfiguration.java index cefff437..346c2ad4 100644 --- a/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/LemonExceptionsAutoConfiguration.java +++ b/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/LemonExceptionsAutoConfiguration.java @@ -1,7 +1,7 @@ package com.naturalprogrammer.spring.lemon.exceptions; -import java.util.List; - +import com.naturalprogrammer.spring.lemon.exceptions.handlers.AbstractExceptionHandler; +import com.naturalprogrammer.spring.lemon.exceptions.util.LexUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.boot.autoconfigure.AutoConfigureBefore; @@ -13,8 +13,7 @@ import org.springframework.context.annotation.Configuration; import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean; -import com.naturalprogrammer.spring.lemon.exceptions.handlers.AbstractExceptionHandler; -import com.naturalprogrammer.spring.lemon.exceptions.util.LexUtils; +import java.util.List; @Configuration @AutoConfigureBefore({ValidationAutoConfiguration.class}) diff --git a/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/LemonFieldError.java b/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/LemonFieldError.java index 31063ae9..26262108 100644 --- a/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/LemonFieldError.java +++ b/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/LemonFieldError.java @@ -1,19 +1,18 @@ package com.naturalprogrammer.spring.lemon.exceptions; -import java.util.List; -import java.util.Set; -import java.util.stream.Collectors; - -import javax.validation.ConstraintViolation; - +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.ToString; import org.apache.commons.lang3.StringUtils; import org.springframework.validation.FieldError; import org.springframework.validation.ObjectError; import org.springframework.web.bind.support.WebExchangeBindException; -import lombok.AllArgsConstructor; -import lombok.Getter; -import lombok.ToString; +import javax.validation.ConstraintViolation; +import java.io.Serializable; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; /** * Holds a field or form error @@ -21,7 +20,7 @@ * @author Sanjay Patel */ @Getter @AllArgsConstructor @ToString -public class LemonFieldError { +public class LemonFieldError implements Serializable { // Name of the field. Null in case of a form level error. private String field; diff --git a/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/MultiErrorException.java b/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/MultiErrorException.java index 6548489a..e8e60f03 100644 --- a/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/MultiErrorException.java +++ b/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/MultiErrorException.java @@ -1,19 +1,16 @@ package com.naturalprogrammer.spring.lemon.exceptions; +import com.naturalprogrammer.spring.lemon.exceptions.util.LexUtils; +import lombok.AccessLevel; +import lombok.Getter; +import org.springframework.http.HttpStatus; + +import javax.validation.ConstraintViolation; import java.util.ArrayList; import java.util.List; import java.util.Set; import java.util.stream.Collectors; -import javax.validation.ConstraintViolation; - -import org.springframework.http.HttpStatus; - -import com.naturalprogrammer.spring.lemon.exceptions.util.LexUtils; - -import lombok.AccessLevel; -import lombok.Getter; - /** * An exception class which can contain multiple errors. * Used for validation, in service classes. diff --git a/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/VersionException.java b/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/VersionException.java index fa74a57b..3395c15d 100644 --- a/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/VersionException.java +++ b/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/VersionException.java @@ -1,10 +1,9 @@ package com.naturalprogrammer.spring.lemon.exceptions; +import com.naturalprogrammer.spring.lemon.exceptions.util.LexUtils; import org.springframework.http.HttpStatus; import org.springframework.web.bind.annotation.ResponseStatus; -import com.naturalprogrammer.spring.lemon.exceptions.util.LexUtils; - /** * Version exception, to be thrown when concurrent * updates of an entity is noticed. diff --git a/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/handlers/AbstractExceptionHandler.java b/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/handlers/AbstractExceptionHandler.java index a7615bfb..a893908a 100644 --- a/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/handlers/AbstractExceptionHandler.java +++ b/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/handlers/AbstractExceptionHandler.java @@ -1,14 +1,13 @@ package com.naturalprogrammer.spring.lemon.exceptions.handlers; -import java.util.Collection; - +import com.naturalprogrammer.spring.lemon.exceptions.ErrorResponse; +import com.naturalprogrammer.spring.lemon.exceptions.LemonFieldError; +import com.naturalprogrammer.spring.lemon.exceptions.util.LexUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.http.HttpStatus; -import com.naturalprogrammer.spring.lemon.exceptions.ErrorResponse; -import com.naturalprogrammer.spring.lemon.exceptions.LemonFieldError; -import com.naturalprogrammer.spring.lemon.exceptions.util.LexUtils; +import java.util.Collection; /** * Extend this to code an exception handler diff --git a/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/handlers/AbstractValidationExceptionHandler.java b/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/handlers/AbstractValidationExceptionHandler.java index e7be3af1..1edd8748 100644 --- a/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/handlers/AbstractValidationExceptionHandler.java +++ b/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/handlers/AbstractValidationExceptionHandler.java @@ -1,11 +1,10 @@ package com.naturalprogrammer.spring.lemon.exceptions.handlers; +import com.naturalprogrammer.spring.lemon.exceptions.util.LexUtils; import org.springframework.core.Ordered; import org.springframework.core.annotation.Order; import org.springframework.http.HttpStatus; -import com.naturalprogrammer.spring.lemon.exceptions.util.LexUtils; - /** * Extend this for any exception handler that should return a 400 response */ diff --git a/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/handlers/ConstraintViolationExceptionHandler.java b/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/handlers/ConstraintViolationExceptionHandler.java index 83c282e5..cac25177 100644 --- a/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/handlers/ConstraintViolationExceptionHandler.java +++ b/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/handlers/ConstraintViolationExceptionHandler.java @@ -1,14 +1,12 @@ package com.naturalprogrammer.spring.lemon.exceptions.handlers; -import java.util.Collection; - -import javax.validation.ConstraintViolationException; - +import com.naturalprogrammer.spring.lemon.exceptions.LemonFieldError; import org.springframework.core.Ordered; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; -import com.naturalprogrammer.spring.lemon.exceptions.LemonFieldError; +import javax.validation.ConstraintViolationException; +import java.util.Collection; @Component @Order(Ordered.LOWEST_PRECEDENCE) diff --git a/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/handlers/MultiErrorExceptionHandler.java b/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/handlers/MultiErrorExceptionHandler.java index 72ea980b..3080cc50 100644 --- a/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/handlers/MultiErrorExceptionHandler.java +++ b/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/handlers/MultiErrorExceptionHandler.java @@ -1,14 +1,13 @@ package com.naturalprogrammer.spring.lemon.exceptions.handlers; -import java.util.Collection; - +import com.naturalprogrammer.spring.lemon.exceptions.LemonFieldError; +import com.naturalprogrammer.spring.lemon.exceptions.MultiErrorException; import org.springframework.core.Ordered; import org.springframework.core.annotation.Order; import org.springframework.http.HttpStatus; import org.springframework.stereotype.Component; -import com.naturalprogrammer.spring.lemon.exceptions.LemonFieldError; -import com.naturalprogrammer.spring.lemon.exceptions.MultiErrorException; +import java.util.Collection; @Component @Order(Ordered.LOWEST_PRECEDENCE) diff --git a/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/handlers/WebExchangeBindExceptionHandler.java b/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/handlers/WebExchangeBindExceptionHandler.java index 1483e576..f2b10b81 100644 --- a/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/handlers/WebExchangeBindExceptionHandler.java +++ b/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/handlers/WebExchangeBindExceptionHandler.java @@ -1,13 +1,12 @@ package com.naturalprogrammer.spring.lemon.exceptions.handlers; -import java.util.Collection; - +import com.naturalprogrammer.spring.lemon.exceptions.LemonFieldError; import org.springframework.core.Ordered; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; import org.springframework.web.bind.support.WebExchangeBindException; -import com.naturalprogrammer.spring.lemon.exceptions.LemonFieldError; +import java.util.Collection; @Component @Order(Ordered.LOWEST_PRECEDENCE) diff --git a/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/util/LexUtils.java b/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/util/LexUtils.java index 0221915d..d58517b2 100644 --- a/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/util/LexUtils.java +++ b/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/util/LexUtils.java @@ -1,10 +1,7 @@ package com.naturalprogrammer.spring.lemon.exceptions.util; -import java.util.function.Supplier; - -import javax.annotation.PostConstruct; -import javax.validation.ConstraintViolationException; - +import com.naturalprogrammer.spring.lemon.exceptions.ExceptionIdMaker; +import com.naturalprogrammer.spring.lemon.exceptions.MultiErrorException; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.context.MessageSource; @@ -12,8 +9,9 @@ import org.springframework.http.HttpStatus; import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean; -import com.naturalprogrammer.spring.lemon.exceptions.ExceptionIdMaker; -import com.naturalprogrammer.spring.lemon.exceptions.MultiErrorException; +import javax.annotation.PostConstruct; +import javax.validation.ConstraintViolationException; +import java.util.function.Supplier; /** * Useful helper methods diff --git a/spring-lemon-jpa/pom.xml b/spring-lemon-jpa/pom.xml index 24f32553..a7a8388b 100644 --- a/spring-lemon-jpa/pom.xml +++ b/spring-lemon-jpa/pom.xml @@ -13,7 +13,7 @@ com.naturalprogrammer spring-lemon - 1.0.0.RC3 + 1.0.0.RC4 diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/LemonAutoConfiguration.java b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/LemonAutoConfiguration.java index 749b66b7..a72423ce 100644 --- a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/LemonAutoConfiguration.java +++ b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/LemonAutoConfiguration.java @@ -1,7 +1,17 @@ package com.naturalprogrammer.spring.lemon; -import java.io.Serializable; - +import com.fasterxml.jackson.databind.ObjectMapper; +import com.naturalprogrammer.spring.lemon.commons.LemonProperties; +import com.naturalprogrammer.spring.lemon.commons.domain.IdConverter; +import com.naturalprogrammer.spring.lemon.commons.security.BlueTokenService; +import com.naturalprogrammer.spring.lemon.commons.validation.RetypePasswordValidator; +import com.naturalprogrammer.spring.lemon.commonsjpa.LemonCommonsJpaAutoConfiguration; +import com.naturalprogrammer.spring.lemon.commonsweb.security.LemonWebSecurityConfig; +import com.naturalprogrammer.spring.lemon.domain.AbstractUser; +import com.naturalprogrammer.spring.lemon.domain.AbstractUserRepository; +import com.naturalprogrammer.spring.lemon.security.*; +import com.naturalprogrammer.spring.lemon.util.LemonUtils; +import com.naturalprogrammer.spring.lemon.validation.UniqueEmailValidator; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.boot.autoconfigure.AutoConfigureBefore; @@ -16,24 +26,7 @@ import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler; import org.springframework.transaction.annotation.EnableTransactionManagement; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.naturalprogrammer.spring.lemon.commons.LemonProperties; -import com.naturalprogrammer.spring.lemon.commons.domain.IdConverter; -import com.naturalprogrammer.spring.lemon.commons.security.BlueTokenService; -import com.naturalprogrammer.spring.lemon.commons.validation.RetypePasswordValidator; -import com.naturalprogrammer.spring.lemon.commonsjpa.LemonCommonsJpaAutoConfiguration; -import com.naturalprogrammer.spring.lemon.commonsweb.security.LemonWebSecurityConfig; -import com.naturalprogrammer.spring.lemon.domain.AbstractUser; -import com.naturalprogrammer.spring.lemon.domain.AbstractUserRepository; -import com.naturalprogrammer.spring.lemon.security.LemonAuthenticationSuccessHandler; -import com.naturalprogrammer.spring.lemon.security.LemonJpaSecurityConfig; -import com.naturalprogrammer.spring.lemon.security.LemonOAuth2UserService; -import com.naturalprogrammer.spring.lemon.security.LemonOidcUserService; -import com.naturalprogrammer.spring.lemon.security.LemonUserDetailsService; -import com.naturalprogrammer.spring.lemon.security.OAuth2AuthenticationFailureHandler; -import com.naturalprogrammer.spring.lemon.security.OAuth2AuthenticationSuccessHandler; -import com.naturalprogrammer.spring.lemon.util.LemonUtils; -import com.naturalprogrammer.spring.lemon.validation.UniqueEmailValidator; +import java.io.Serializable; /** * Spring Lemon Auto Configuration @@ -56,7 +49,7 @@ public LemonAutoConfiguration() { @ConditionalOnMissingBean(IdConverter.class) public IdConverter idConverter(LemonService lemonService) { - return id -> lemonService.toId(id); + return lemonService::toId; } /** diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/LemonController.java b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/LemonController.java index 5a9fbc18..3f5576ef 100644 --- a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/LemonController.java +++ b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/LemonController.java @@ -1,28 +1,6 @@ package com.naturalprogrammer.spring.lemon; -import java.io.IOException; -import java.io.Serializable; -import java.util.Map; -import java.util.Optional; - -import javax.servlet.http.HttpServletResponse; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpStatus; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PatchMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestHeader; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.ResponseStatus; - import com.fasterxml.jackson.annotation.JsonView; -import com.fasterxml.jackson.core.JsonProcessingException; import com.github.fge.jsonpatch.JsonPatchException; import com.naturalprogrammer.spring.lemon.commons.LemonProperties; import com.naturalprogrammer.spring.lemon.commons.domain.ChangePasswordForm; @@ -33,6 +11,18 @@ import com.naturalprogrammer.spring.lemon.commonsweb.util.LecwUtils; import com.naturalprogrammer.spring.lemon.domain.AbstractUser; import com.naturalprogrammer.spring.lemon.exceptions.util.LexUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.*; + +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.io.Serializable; +import java.util.Map; +import java.util.Optional; /** * The Lemon API. See the @@ -192,7 +182,7 @@ public UserDto updateUser( @PathVariable("id") U user, @RequestBody String patch, HttpServletResponse response) - throws JsonProcessingException, IOException, JsonPatchException { + throws IOException, JsonPatchException { log.debug("Updating user ... "); diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/LemonService.java b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/LemonService.java index 66014dd5..56755c8c 100644 --- a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/LemonService.java +++ b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/LemonService.java @@ -1,35 +1,7 @@ package com.naturalprogrammer.spring.lemon; -import java.io.Serializable; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; -import java.util.Optional; - -import javax.servlet.http.HttpServletResponse; -import javax.validation.Valid; -import javax.validation.constraints.Email; -import javax.validation.constraints.NotBlank; - -import org.apache.commons.lang3.StringUtils; -import org.apache.commons.lang3.exception.ExceptionUtils; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.context.event.ApplicationReadyEvent; -import org.springframework.context.event.EventListener; -import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.security.core.userdetails.UserDetailsService; -import org.springframework.security.core.userdetails.UsernameNotFoundException; -import org.springframework.security.crypto.password.PasswordEncoder; -import org.springframework.security.oauth2.core.oidc.StandardClaimNames; -import org.springframework.transaction.annotation.Propagation; -import org.springframework.transaction.annotation.Transactional; -import org.springframework.validation.annotation.Validated; - import com.naturalprogrammer.spring.lemon.commons.AbstractLemonService; import com.naturalprogrammer.spring.lemon.commons.LemonProperties; -import com.naturalprogrammer.spring.lemon.commons.LemonProperties.Admin; import com.naturalprogrammer.spring.lemon.commons.domain.ChangePasswordForm; import com.naturalprogrammer.spring.lemon.commons.domain.ResetPasswordForm; import com.naturalprogrammer.spring.lemon.commons.mail.LemonMailData; @@ -47,6 +19,27 @@ import com.naturalprogrammer.spring.lemon.exceptions.util.LexUtils; import com.naturalprogrammer.spring.lemon.util.LemonUtils; import com.nimbusds.jwt.JWTClaimsSet; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.exception.ExceptionUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.core.userdetails.UsernameNotFoundException; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.transaction.annotation.Propagation; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.validation.annotation.Validated; + +import javax.servlet.http.HttpServletResponse; +import javax.validation.Valid; +import javax.validation.constraints.Email; +import javax.validation.constraints.NotBlank; +import java.io.Serializable; +import java.util.Collections; +import java.util.Map; +import java.util.Optional; /** * The Lemon Service class @@ -176,6 +169,7 @@ public void signup(@Valid U user) { * Initializes the user based on the input data, * e.g. encrypts the password */ + @Override protected void initUser(U user) { log.debug("Initializing user: " + user); @@ -188,6 +182,7 @@ protected void initUser(U user) { /** * Makes a user unverified */ + @Override protected void makeUnverified(U user) { super.makeUnverified(user); @@ -319,13 +314,8 @@ public void resetPassword(@Valid ResetPasswordForm form) { userRepository.save(user); // after successful commit, - LecjUtils.afterCommit(() -> { - - // Login the user - LemonUtils.login(user); - }); - - log.debug("Password reset."); + LecjUtils.afterCommit(() -> LemonUtils.login(user)); + log.debug("Password reset."); } @@ -476,7 +466,7 @@ protected void mailChangeEmailLink(U user) { log.debug("Change email link mail queued."); - } catch (Throwable e) { + } catch (Exception e) { // In case of exception, just log the error and keep silent log.error(ExceptionUtils.getStackTrace(e)); } @@ -546,12 +536,7 @@ public void changeEmail(ID userId, @Valid @NotBlank String changeEmailCode) { userRepository.save(user); // after successful commit, - LecjUtils.afterCommit(() -> { - - // Login the user - LemonUtils.login(user); - }); - + LecjUtils.afterCommit(() -> LemonUtils.login(user)); log.debug("Changed email of user: " + user); } @@ -611,12 +596,10 @@ public Map fetchFullToken(String authHeader) { Map claimMap = Collections.singletonMap(BlueTokenService.USER_CLAIM, LecUtils.serialize(currentUser)); // Not serializing converts it to a JsonNode - Map tokenMap = Collections.singletonMap("token", LecUtils.TOKEN_PREFIX + + return Collections.singletonMap("token", LecUtils.TOKEN_PREFIX + blueTokenService.createToken(BlueTokenService.AUTH_AUDIENCE, currentUser.getUsername(), Long.valueOf(properties.getJwt().getShortLivedMillis()), claimMap)); - - return tokenMap; } diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/domain/AbstractUser.java b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/domain/AbstractUser.java index 4e1b4724..cd2360f8 100644 --- a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/domain/AbstractUser.java +++ b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/domain/AbstractUser.java @@ -1,17 +1,5 @@ package com.naturalprogrammer.spring.lemon.domain; -import java.io.Serializable; -import java.util.HashSet; -import java.util.Set; - -import javax.persistence.CollectionTable; -import javax.persistence.Column; -import javax.persistence.ElementCollection; -import javax.persistence.FetchType; -import javax.persistence.JoinColumn; -import javax.persistence.MappedSuperclass; -import javax.persistence.Transient; - import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonView; import com.naturalprogrammer.spring.lemon.commons.domain.LemonUser; @@ -21,10 +9,14 @@ import com.naturalprogrammer.spring.lemon.commons.validation.Password; import com.naturalprogrammer.spring.lemon.commonsjpa.LemonEntity; import com.naturalprogrammer.spring.lemon.validation.UniqueEmail; - import lombok.Getter; import lombok.Setter; +import javax.persistence.*; +import java.io.Serializable; +import java.util.HashSet; +import java.util.Set; + /** * Base class for User entity diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/domain/AbstractUserRepository.java b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/domain/AbstractUserRepository.java index fb7bb065..e91bad07 100644 --- a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/domain/AbstractUserRepository.java +++ b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/domain/AbstractUserRepository.java @@ -1,11 +1,11 @@ package com.naturalprogrammer.spring.lemon.domain; -import java.io.Serializable; -import java.util.Optional; - import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.repository.NoRepositoryBean; +import java.io.Serializable; +import java.util.Optional; + /** * Abstract UserRepository interface * diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/HttpCookieOAuth2AuthorizationRequestRepository.java b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/HttpCookieOAuth2AuthorizationRequestRepository.java index 00939ea8..80810666 100644 --- a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/HttpCookieOAuth2AuthorizationRequestRepository.java +++ b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/HttpCookieOAuth2AuthorizationRequestRepository.java @@ -1,18 +1,17 @@ package com.naturalprogrammer.spring.lemon.security; -import javax.servlet.http.Cookie; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - +import com.naturalprogrammer.spring.lemon.commons.LemonProperties; +import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; +import com.naturalprogrammer.spring.lemon.commonsweb.util.LecwUtils; import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.StringUtils; import org.springframework.security.oauth2.client.web.AuthorizationRequestRepository; import org.springframework.security.oauth2.core.endpoint.OAuth2AuthorizationRequest; import org.springframework.util.Assert; -import com.naturalprogrammer.spring.lemon.commons.LemonProperties; -import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; -import com.naturalprogrammer.spring.lemon.commonsweb.util.LecwUtils; +import javax.servlet.http.Cookie; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; /** * Cookie based repository for storing Authorization requests diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonAuthenticationSuccessHandler.java b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonAuthenticationSuccessHandler.java index fce739a8..b0368f37 100644 --- a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonAuthenticationSuccessHandler.java +++ b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonAuthenticationSuccessHandler.java @@ -1,22 +1,20 @@ package com.naturalprogrammer.spring.lemon.security; -import java.io.IOException; - -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - +import com.fasterxml.jackson.databind.ObjectMapper; +import com.naturalprogrammer.spring.lemon.LemonService; +import com.naturalprogrammer.spring.lemon.commons.LemonProperties; +import com.naturalprogrammer.spring.lemon.commons.security.UserDto; +import com.naturalprogrammer.spring.lemon.commonsweb.util.LecwUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.http.MediaType; import org.springframework.security.core.Authentication; import org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.naturalprogrammer.spring.lemon.LemonService; -import com.naturalprogrammer.spring.lemon.commons.LemonProperties; -import com.naturalprogrammer.spring.lemon.commons.security.UserDto; -import com.naturalprogrammer.spring.lemon.commonsweb.util.LecwUtils; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; /** * Authentication success handler for sending the response diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonJpaSecurityConfig.java b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonJpaSecurityConfig.java index afaead2e..60282d5d 100644 --- a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonJpaSecurityConfig.java +++ b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonJpaSecurityConfig.java @@ -1,16 +1,14 @@ package com.naturalprogrammer.spring.lemon.security; +import com.naturalprogrammer.spring.lemon.commons.LemonProperties; +import com.naturalprogrammer.spring.lemon.commonsweb.security.LemonWebSecurityConfig; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.config.annotation.web.builders.HttpSecurity; -import org.springframework.security.config.http.SessionCreationPolicy; import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; -import com.naturalprogrammer.spring.lemon.commons.LemonProperties; -import com.naturalprogrammer.spring.lemon.commonsweb.security.LemonWebSecurityConfig; - /** * Security configuration class. Extend it in the * application, and make a configuration class. Override @@ -114,7 +112,7 @@ protected void oauth2Client(HttpSecurity http) throws Exception { * Configuring token authentication filter */ @Override - protected void tokenAuthentication(HttpSecurity http) throws Exception { + protected void tokenAuthentication(HttpSecurity http) { http.addFilterBefore(new LemonJpaTokenAuthenticationFilter(blueTokenService, userDetailsService), UsernamePasswordAuthenticationFilter.class); diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonJpaTokenAuthenticationFilter.java b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonJpaTokenAuthenticationFilter.java index 49c6b840..1815fcae 100644 --- a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonJpaTokenAuthenticationFilter.java +++ b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonJpaTokenAuthenticationFilter.java @@ -1,17 +1,16 @@ package com.naturalprogrammer.spring.lemon.security; -import java.io.Serializable; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.springframework.security.core.userdetails.UsernameNotFoundException; - import com.naturalprogrammer.spring.lemon.commons.security.BlueTokenService; import com.naturalprogrammer.spring.lemon.commons.security.UserDto; import com.naturalprogrammer.spring.lemon.commonsweb.security.LemonCommonsWebTokenAuthenticationFilter; import com.naturalprogrammer.spring.lemon.domain.AbstractUser; import com.naturalprogrammer.spring.lemon.util.LemonUtils; import com.nimbusds.jwt.JWTClaimsSet; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.springframework.security.core.userdetails.UsernameNotFoundException; + +import java.io.Serializable; public class LemonJpaTokenAuthenticationFilter, ID extends Serializable> extends LemonCommonsWebTokenAuthenticationFilter { diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonOAuth2UserService.java b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonOAuth2UserService.java index d588e64c..d4e6e0d2 100644 --- a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonOAuth2UserService.java +++ b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonOAuth2UserService.java @@ -1,12 +1,11 @@ package com.naturalprogrammer.spring.lemon.security; -import java.io.Serializable; -import java.nio.charset.StandardCharsets; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Map; - +import com.naturalprogrammer.spring.lemon.LemonService; +import com.naturalprogrammer.spring.lemon.commons.security.LemonPrincipal; +import com.naturalprogrammer.spring.lemon.commons.security.UserDto; +import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; +import com.naturalprogrammer.spring.lemon.domain.AbstractUser; +import com.naturalprogrammer.spring.lemon.exceptions.util.LexUtils; import org.apache.commons.lang3.exception.ExceptionUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -17,17 +16,16 @@ import org.springframework.security.oauth2.client.http.OAuth2ErrorResponseErrorHandler; import org.springframework.security.oauth2.client.userinfo.DefaultOAuth2UserService; import org.springframework.security.oauth2.client.userinfo.OAuth2UserRequest; -import org.springframework.security.oauth2.core.OAuth2AuthenticationException; import org.springframework.security.oauth2.core.user.OAuth2User; import org.springframework.util.MimeType; import org.springframework.web.client.RestTemplate; -import com.naturalprogrammer.spring.lemon.LemonService; -import com.naturalprogrammer.spring.lemon.commons.security.LemonPrincipal; -import com.naturalprogrammer.spring.lemon.commons.security.UserDto; -import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; -import com.naturalprogrammer.spring.lemon.domain.AbstractUser; -import com.naturalprogrammer.spring.lemon.exceptions.util.LexUtils; +import java.io.Serializable; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Map; /** * Logs in or registers a user after OAuth2 SignIn/Up @@ -77,7 +75,7 @@ protected List> makeMessageConverters() { } @Override - public OAuth2User loadUser(OAuth2UserRequest userRequest) throws OAuth2AuthenticationException { + public OAuth2User loadUser(OAuth2UserRequest userRequest) { OAuth2User oath2User = super.loadUser(userRequest); return buildPrincipal(oath2User, userRequest.getClientRegistration().getRegistrationId()); @@ -110,7 +108,7 @@ public LemonPrincipal buildPrincipal(OAuth2User oath2User, String registrationId lemonService.mailForgotPasswordLink(newUser); - } catch (Throwable e) { + } catch (Exception e) { // In case of exception, just log the error and keep silent log.error(ExceptionUtils.getStackTrace(e)); diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonOidcUserService.java b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonOidcUserService.java index a9740a96..41edcbc4 100644 --- a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonOidcUserService.java +++ b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonOidcUserService.java @@ -1,14 +1,12 @@ package com.naturalprogrammer.spring.lemon.security; +import com.naturalprogrammer.spring.lemon.commons.security.LemonPrincipal; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.security.oauth2.client.oidc.userinfo.OidcUserRequest; import org.springframework.security.oauth2.client.oidc.userinfo.OidcUserService; -import org.springframework.security.oauth2.core.OAuth2AuthenticationException; import org.springframework.security.oauth2.core.oidc.user.OidcUser; -import com.naturalprogrammer.spring.lemon.commons.security.LemonPrincipal; - /** * Logs in or registers a user after OpenID Connect SignIn/Up */ @@ -25,7 +23,7 @@ public LemonOidcUserService(LemonOAuth2UserService oauth2UserService) { } @Override - public OidcUser loadUser(OidcUserRequest userRequest) throws OAuth2AuthenticationException { + public OidcUser loadUser(OidcUserRequest userRequest) { OidcUser oidcUser = super.loadUser(userRequest); LemonPrincipal principal = oauth2UserService.buildPrincipal(oidcUser, diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonUserDetailsService.java b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonUserDetailsService.java index f0d46230..a0e8dbce 100644 --- a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonUserDetailsService.java +++ b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonUserDetailsService.java @@ -1,17 +1,16 @@ package com.naturalprogrammer.spring.lemon.security; -import java.io.Serializable; -import java.util.Optional; - +import com.naturalprogrammer.spring.lemon.commons.security.LemonPrincipal; +import com.naturalprogrammer.spring.lemon.domain.AbstractUser; +import com.naturalprogrammer.spring.lemon.domain.AbstractUserRepository; +import com.naturalprogrammer.spring.lemon.exceptions.util.LexUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.core.userdetails.UsernameNotFoundException; -import com.naturalprogrammer.spring.lemon.commons.security.LemonPrincipal; -import com.naturalprogrammer.spring.lemon.domain.AbstractUser; -import com.naturalprogrammer.spring.lemon.domain.AbstractUserRepository; -import com.naturalprogrammer.spring.lemon.exceptions.util.LexUtils; +import java.io.Serializable; +import java.util.Optional; /** * UserDetailsService, as required by Spring Security. @@ -33,8 +32,7 @@ public LemonUserDetailsService(AbstractUserRepository userRepository) { } @Override - public LemonPrincipal loadUserByUsername(String username) - throws UsernameNotFoundException { + public LemonPrincipal loadUserByUsername(String username) { log.debug("Loading user having username: " + username); diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/OAuth2AuthenticationFailureHandler.java b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/OAuth2AuthenticationFailureHandler.java index 15ba9343..643dff95 100644 --- a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/OAuth2AuthenticationFailureHandler.java +++ b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/OAuth2AuthenticationFailureHandler.java @@ -1,15 +1,13 @@ package com.naturalprogrammer.spring.lemon.security; -import java.io.IOException; +import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; +import org.springframework.security.core.AuthenticationException; +import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; - -import org.springframework.security.core.AuthenticationException; -import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler; - -import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; +import java.io.IOException; /** * OAuth2 Authentication failure handler for removing oauth2 related cookies diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/OAuth2AuthenticationSuccessHandler.java b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/OAuth2AuthenticationSuccessHandler.java index c9734664..7401ffab 100644 --- a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/OAuth2AuthenticationSuccessHandler.java +++ b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/OAuth2AuthenticationSuccessHandler.java @@ -1,20 +1,18 @@ package com.naturalprogrammer.spring.lemon.security; -import javax.servlet.http.Cookie; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler; - import com.naturalprogrammer.spring.lemon.commons.LemonProperties; import com.naturalprogrammer.spring.lemon.commons.security.BlueTokenService; import com.naturalprogrammer.spring.lemon.commons.security.UserDto; import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; import com.naturalprogrammer.spring.lemon.commonsweb.util.LecwUtils; - import lombok.AllArgsConstructor; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler; + +import javax.servlet.http.Cookie; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; /** * Authentication success handler for redirecting the diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/util/LemonUtils.java b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/util/LemonUtils.java index 7b4e824b..1fed8d6b 100644 --- a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/util/LemonUtils.java +++ b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/util/LemonUtils.java @@ -1,18 +1,17 @@ package com.naturalprogrammer.spring.lemon.util; -import java.io.Serializable; - +import com.naturalprogrammer.spring.lemon.commons.security.LemonPrincipal; +import com.naturalprogrammer.spring.lemon.commons.security.LemonTokenService; +import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; +import com.naturalprogrammer.spring.lemon.domain.AbstractUser; +import com.nimbusds.jwt.JWTClaimsSet; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContextHolder; -import com.naturalprogrammer.spring.lemon.commons.security.LemonPrincipal; -import com.naturalprogrammer.spring.lemon.commons.security.LemonTokenService; -import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; -import com.naturalprogrammer.spring.lemon.domain.AbstractUser; -import com.nimbusds.jwt.JWTClaimsSet; +import java.io.Serializable; /** * Useful helper methods diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/validation/UniqueEmail.java b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/validation/UniqueEmail.java index bde77376..02b094a4 100644 --- a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/validation/UniqueEmail.java +++ b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/validation/UniqueEmail.java @@ -1,14 +1,13 @@ package com.naturalprogrammer.spring.lemon.validation; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; +import com.naturalprogrammer.spring.lemon.commons.util.UserUtils; import javax.validation.Constraint; import javax.validation.constraints.Email; import javax.validation.constraints.NotBlank; import javax.validation.constraints.Size; - -import com.naturalprogrammer.spring.lemon.commons.util.UserUtils; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; /** * Annotation for unique-email constraint, diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/validation/UniqueEmailValidator.java b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/validation/UniqueEmailValidator.java index 7ddbc356..68a7bc78 100644 --- a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/validation/UniqueEmailValidator.java +++ b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/validation/UniqueEmailValidator.java @@ -1,12 +1,11 @@ package com.naturalprogrammer.spring.lemon.validation; -import javax.validation.ConstraintValidator; -import javax.validation.ConstraintValidatorContext; - +import com.naturalprogrammer.spring.lemon.domain.AbstractUserRepository; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import com.naturalprogrammer.spring.lemon.domain.AbstractUserRepository; +import javax.validation.ConstraintValidator; +import javax.validation.ConstraintValidatorContext; /** * Validator for unique-email diff --git a/spring-lemon-reactive/pom.xml b/spring-lemon-reactive/pom.xml index 24c6821a..a9e8eb68 100644 --- a/spring-lemon-reactive/pom.xml +++ b/spring-lemon-reactive/pom.xml @@ -13,7 +13,7 @@ com.naturalprogrammer spring-lemon - 1.0.0.RC3 + 1.0.0.RC4 diff --git a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveAutoConfiguration.java b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveAutoConfiguration.java index 7f15c203..f9547296 100644 --- a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveAutoConfiguration.java +++ b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveAutoConfiguration.java @@ -1,17 +1,5 @@ package com.naturalprogrammer.spring.lemonreactive; -import java.io.Serializable; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.springframework.boot.autoconfigure.AutoConfigureBefore; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.security.reactive.ReactiveUserDetailsServiceAutoConfiguration; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.security.core.userdetails.UserDetailsService; -import org.springframework.security.crypto.password.PasswordEncoder; - import com.naturalprogrammer.spring.lemon.commons.LemonProperties; import com.naturalprogrammer.spring.lemon.commons.domain.IdConverter; import com.naturalprogrammer.spring.lemon.commons.security.BlueTokenService; @@ -23,6 +11,17 @@ import com.naturalprogrammer.spring.lemonreactive.security.LemonReactiveUserDetailsService; import com.naturalprogrammer.spring.lemonreactive.security.ReactiveOAuth2AuthenticationSuccessHandler; import com.naturalprogrammer.spring.lemonreactive.util.LerUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.springframework.boot.autoconfigure.AutoConfigureBefore; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.security.reactive.ReactiveUserDetailsServiceAutoConfiguration; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.crypto.password.PasswordEncoder; + +import java.io.Serializable; @Configuration @AutoConfigureBefore({ @@ -40,7 +39,7 @@ public LemonReactiveAutoConfiguration() { @ConditionalOnMissingBean(IdConverter.class) public IdConverter idConverter(LemonReactiveService lemonService) { - return id -> lemonService.toId(id); + return lemonService::toId; } @Bean diff --git a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveController.java b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveController.java index b8ced1a4..0c5eca16 100644 --- a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveController.java +++ b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveController.java @@ -1,12 +1,12 @@ package com.naturalprogrammer.spring.lemonreactive; -import java.io.Serializable; -import java.util.Map; -import java.util.Optional; - -import javax.validation.Valid; -import javax.validation.constraints.NotBlank; - +import com.naturalprogrammer.spring.lemon.commons.LemonProperties; +import com.naturalprogrammer.spring.lemon.commons.domain.ChangePasswordForm; +import com.naturalprogrammer.spring.lemon.commons.domain.ResetPasswordForm; +import com.naturalprogrammer.spring.lemon.commons.security.LemonPrincipal; +import com.naturalprogrammer.spring.lemon.commons.security.UserDto; +import com.naturalprogrammer.spring.lemonreactive.domain.AbstractMongoUser; +import com.naturalprogrammer.spring.lemonreactive.forms.EmailForm; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -16,27 +16,17 @@ import org.springframework.security.core.Authentication; import org.springframework.security.core.context.ReactiveSecurityContextHolder; import org.springframework.security.core.context.SecurityContext; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PatchMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestHeader; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.ResponseStatus; +import org.springframework.web.bind.annotation.*; import org.springframework.web.server.ServerWebExchange; - -import com.naturalprogrammer.spring.lemon.commons.LemonProperties; -import com.naturalprogrammer.spring.lemon.commons.domain.ChangePasswordForm; -import com.naturalprogrammer.spring.lemon.commons.domain.ResetPasswordForm; -import com.naturalprogrammer.spring.lemon.commons.security.LemonPrincipal; -import com.naturalprogrammer.spring.lemon.commons.security.UserDto; -import com.naturalprogrammer.spring.lemonreactive.domain.AbstractMongoUser; -import com.naturalprogrammer.spring.lemonreactive.forms.EmailForm; - import reactor.core.publisher.Mono; import reactor.util.function.Tuple2; +import javax.validation.Valid; +import javax.validation.constraints.NotBlank; +import java.io.Serializable; +import java.util.Map; +import java.util.Optional; + /** * The Lemon Mongo API. See the * @@ -112,9 +102,7 @@ public Mono> getContext( return lemonReactiveService .getContext(expirationMillis, response) - .doOnNext(context -> { - log.debug("Returning context " + context); - }); + .doOnNext(context -> log.debug("Returning context " + context)); } diff --git a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveService.java b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveService.java index fb502960..adedbace 100644 --- a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveService.java +++ b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveService.java @@ -1,29 +1,7 @@ package com.naturalprogrammer.spring.lemonreactive; -import java.io.Serializable; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; -import java.util.Optional; - -import org.apache.commons.lang3.StringUtils; -import org.apache.commons.lang3.exception.ExceptionUtils; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.context.event.ApplicationReadyEvent; -import org.springframework.context.event.EventListener; -import org.springframework.http.server.reactive.ServerHttpResponse; -import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.security.core.userdetails.ReactiveUserDetailsService; -import org.springframework.security.core.userdetails.UsernameNotFoundException; -import org.springframework.security.crypto.password.PasswordEncoder; -import org.springframework.util.MultiValueMap; -import org.springframework.web.server.ServerWebExchange; - import com.naturalprogrammer.spring.lemon.commons.AbstractLemonService; import com.naturalprogrammer.spring.lemon.commons.LemonProperties; -import com.naturalprogrammer.spring.lemon.commons.LemonProperties.Admin; import com.naturalprogrammer.spring.lemon.commons.domain.ChangePasswordForm; import com.naturalprogrammer.spring.lemon.commons.domain.ResetPasswordForm; import com.naturalprogrammer.spring.lemon.commons.mail.LemonMailData; @@ -41,12 +19,28 @@ import com.naturalprogrammer.spring.lemonreactive.forms.EmailForm; import com.naturalprogrammer.spring.lemonreactive.util.LerUtils; import com.nimbusds.jwt.JWTClaimsSet; - +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.exception.ExceptionUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.server.reactive.ServerHttpResponse; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.security.core.userdetails.ReactiveUserDetailsService; +import org.springframework.security.core.userdetails.UsernameNotFoundException; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.util.MultiValueMap; +import org.springframework.web.server.ServerWebExchange; import reactor.core.publisher.Mono; import reactor.util.function.Tuple2; import reactor.util.function.Tuple3; import reactor.util.function.Tuples; +import java.io.Serializable; +import java.util.Collections; +import java.util.Map; +import java.util.Optional; + public abstract class LemonReactiveService , ID extends Serializable> extends AbstractLemonService { @@ -85,9 +79,9 @@ public void onStartup() { // Doesn't exist. So, create it. log.debug("Creating first admin ... "); U user = createAdminUser(); - userRepository.insert(user).doOnError(err -> { - log.warn("Error creating initial admin " + err); - }).subscribe(); + userRepository.insert(user) + .doOnError(err -> log.warn("Error creating initial admin " + err)) + .subscribe(); log.debug("Created first admin."); }).subscribe(); } @@ -489,7 +483,6 @@ public Mono requestEmailChange(ID userId, Mono emailForm) { protected void requestEmailChange(Tuple3 tuple) { U user = tuple.getT1(); - U loggedIn = tuple.getT2(); EmailForm emailForm = tuple.getT3(); log.debug("Requesting email change: " + user); @@ -502,7 +495,6 @@ protected void requestEmailChange(Tuple3 tuple) { // preserves the new email id user.setNewEmail(emailForm.getNewEmail()); - log.debug("Requested email change: " + user); } @@ -531,7 +523,7 @@ protected void mailChangeEmailLink(U user) { log.debug("Change email link mail queued."); - } catch (Throwable e) { + } catch (Exception e) { // In case of exception, just log the error and keep silent log.error(ExceptionUtils.getStackTrace(e)); } @@ -560,10 +552,9 @@ public Mono changeEmail(ID userId, Mono> log.debug("Changing email of current user ..."); return LecrUtils.currentUser() - .doOnNext(currentUser -> { + .doOnNext(currentUser -> LexUtils.validate(userId.equals(toId(currentUser.get().getId())), - "com.naturalprogrammer.spring.wrong.login").go(); - }) + "com.naturalprogrammer.spring.wrong.login").go()) .then(Mono.zip(findUserById(userId), formData)) .map(this::validateChangeEmail) .flatMap(user -> Mono.zip(Mono.just(user), @@ -629,7 +620,7 @@ public Mono> fetchNewToken(ServerWebExchange exchange) { return Mono.zip(LecrUtils.currentUser(), exchange.getFormData()).map(tuple -> { - UserDto currentUser = (UserDto) tuple.getT1().get(); + UserDto currentUser = tuple.getT1().get(); String username = tuple.getT2().getFirst("username"); if (StringUtils.isBlank(username)) @@ -659,12 +650,10 @@ public Mono> fetchFullToken(String authHeader) { Map claimMap = Collections.singletonMap(BlueTokenService.USER_CLAIM, LecUtils.serialize(currentUser)); // Not serializing converts it to a JsonNode - Map tokenMap = Collections.singletonMap("token", LecUtils.TOKEN_PREFIX + + return Collections.singletonMap("token", LecUtils.TOKEN_PREFIX + blueTokenService.createToken(BlueTokenService.AUTH_AUDIENCE, currentUser.getUsername(), Long.valueOf(properties.getJwt().getShortLivedMillis()), claimMap)); - - return tokenMap; }); } diff --git a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/domain/AbstractMongoUser.java b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/domain/AbstractMongoUser.java index d778c226..26f169c9 100644 --- a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/domain/AbstractMongoUser.java +++ b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/domain/AbstractMongoUser.java @@ -1,13 +1,5 @@ package com.naturalprogrammer.spring.lemonreactive.domain; -import java.io.Serializable; -import java.util.HashSet; -import java.util.Set; - -import org.springframework.data.annotation.Transient; -import org.springframework.data.mongodb.core.index.Indexed; -import org.springframework.security.core.CredentialsContainer; - import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonView; import com.naturalprogrammer.spring.lemon.commons.domain.LemonUser; @@ -17,9 +9,15 @@ import com.naturalprogrammer.spring.lemon.commons.validation.Password; import com.naturalprogrammer.spring.lemon.commonsmongo.AbstractDocument; import com.naturalprogrammer.spring.lemonreactive.validation.UniqueEmail; - import lombok.Getter; import lombok.Setter; +import org.springframework.data.annotation.Transient; +import org.springframework.data.mongodb.core.index.Indexed; +import org.springframework.security.core.CredentialsContainer; + +import java.io.Serializable; +import java.util.HashSet; +import java.util.Set; @Getter @Setter public abstract class AbstractMongoUser diff --git a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/domain/AbstractMongoUserRepository.java b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/domain/AbstractMongoUserRepository.java index 53f3a78c..ebefc220 100644 --- a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/domain/AbstractMongoUserRepository.java +++ b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/domain/AbstractMongoUserRepository.java @@ -1,12 +1,11 @@ package com.naturalprogrammer.spring.lemonreactive.domain; -import java.io.Serializable; - import org.springframework.data.mongodb.repository.ReactiveMongoRepository; import org.springframework.data.repository.NoRepositoryBean; - import reactor.core.publisher.Mono; +import java.io.Serializable; + /** * Abstract UserRepository interface * diff --git a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/forms/EmailForm.java b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/forms/EmailForm.java index 4e727acf..baca57b1 100644 --- a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/forms/EmailForm.java +++ b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/forms/EmailForm.java @@ -2,7 +2,6 @@ import com.naturalprogrammer.spring.lemon.commons.validation.Password; import com.naturalprogrammer.spring.lemonreactive.validation.UniqueEmail; - import lombok.Getter; import lombok.Setter; diff --git a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/security/LemonReactiveSecurityConfig.java b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/security/LemonReactiveSecurityConfig.java index a1d6dc12..371d1a50 100644 --- a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/security/LemonReactiveSecurityConfig.java +++ b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/security/LemonReactiveSecurityConfig.java @@ -1,16 +1,5 @@ package com.naturalprogrammer.spring.lemonreactive.security; -import java.io.Serializable; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.springframework.security.config.web.server.ServerHttpSecurity; -import org.springframework.security.core.AuthenticationException; -import org.springframework.security.core.userdetails.UsernameNotFoundException; -import org.springframework.security.web.server.WebFilterExchange; -import org.springframework.security.web.server.authentication.WebFilterChainServerAuthenticationSuccessHandler; -import org.springframework.security.web.server.context.NoOpServerSecurityContextRepository; - import com.naturalprogrammer.spring.lemon.commons.LemonProperties; import com.naturalprogrammer.spring.lemon.commons.security.BlueTokenService; import com.naturalprogrammer.spring.lemon.commons.security.UserDto; @@ -19,9 +8,18 @@ import com.naturalprogrammer.spring.lemonreactive.domain.AbstractMongoUser; import com.naturalprogrammer.spring.lemonreactive.util.LerUtils; import com.nimbusds.jwt.JWTClaimsSet; - +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.springframework.security.config.web.server.ServerHttpSecurity; +import org.springframework.security.core.AuthenticationException; +import org.springframework.security.core.userdetails.UsernameNotFoundException; +import org.springframework.security.web.server.WebFilterExchange; +import org.springframework.security.web.server.authentication.WebFilterChainServerAuthenticationSuccessHandler; +import org.springframework.security.web.server.context.NoOpServerSecurityContextRepository; import reactor.core.publisher.Mono; +import java.io.Serializable; + public class LemonReactiveSecurityConfig, ID extends Serializable> extends LemonCommonsReactiveSecurityConfig { private static final Log log = LogFactory.getLog(LemonReactiveSecurityConfig.class); diff --git a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/security/LemonReactiveUserDetailsService.java b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/security/LemonReactiveUserDetailsService.java index 8b72a9e1..3b166f5f 100644 --- a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/security/LemonReactiveUserDetailsService.java +++ b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/security/LemonReactiveUserDetailsService.java @@ -1,20 +1,18 @@ package com.naturalprogrammer.spring.lemonreactive.security; -import java.io.Serializable; - +import com.naturalprogrammer.spring.lemon.commons.security.LemonPrincipal; +import com.naturalprogrammer.spring.lemon.exceptions.util.LexUtils; +import com.naturalprogrammer.spring.lemonreactive.domain.AbstractMongoUser; +import com.naturalprogrammer.spring.lemonreactive.domain.AbstractMongoUserRepository; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.security.core.userdetails.ReactiveUserDetailsService; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UsernameNotFoundException; - -import com.naturalprogrammer.spring.lemon.commons.security.LemonPrincipal; -import com.naturalprogrammer.spring.lemon.exceptions.util.LexUtils; -import com.naturalprogrammer.spring.lemonreactive.domain.AbstractMongoUser; -import com.naturalprogrammer.spring.lemonreactive.domain.AbstractMongoUserRepository; - import reactor.core.publisher.Mono; +import java.io.Serializable; + public class LemonReactiveUserDetailsService, ID extends Serializable> implements ReactiveUserDetailsService { diff --git a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/security/ReactiveCookieServerOAuth2AuthorizedClientRepository.java b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/security/ReactiveCookieServerOAuth2AuthorizedClientRepository.java index b0f5c710..4f43d91f 100644 --- a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/security/ReactiveCookieServerOAuth2AuthorizedClientRepository.java +++ b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/security/ReactiveCookieServerOAuth2AuthorizedClientRepository.java @@ -1,7 +1,8 @@ package com.naturalprogrammer.spring.lemonreactive.security; -import java.util.Collections; - +import com.naturalprogrammer.spring.lemon.commons.LemonProperties; +import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; +import com.naturalprogrammer.spring.lemon.commonsreactive.util.LecrUtils; import org.apache.commons.lang3.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -14,13 +15,10 @@ import org.springframework.util.Assert; import org.springframework.util.MultiValueMap; import org.springframework.web.server.ServerWebExchange; - -import com.naturalprogrammer.spring.lemon.commons.LemonProperties; -import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; -import com.naturalprogrammer.spring.lemon.commonsreactive.util.LecrUtils; - import reactor.core.publisher.Mono; +import java.util.Collections; + public class ReactiveCookieServerOAuth2AuthorizedClientRepository implements ServerOAuth2AuthorizedClientRepository { private static final Log log = LogFactory.getLog(ReactiveCookieServerOAuth2AuthorizedClientRepository.class); @@ -112,7 +110,7 @@ public static void deleteCookies(ServerWebExchange exchange, String ...cookiesTo .build(); responseCookies.put(cookiesToDelete[i], Collections.singletonList(cookie)); - }; + } } private Mono deserialize(HttpCookie cookie) { diff --git a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/security/ReactiveOAuth2AuthenticationSuccessHandler.java b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/security/ReactiveOAuth2AuthenticationSuccessHandler.java index 44151b9a..9007cb24 100644 --- a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/security/ReactiveOAuth2AuthenticationSuccessHandler.java +++ b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/security/ReactiveOAuth2AuthenticationSuccessHandler.java @@ -1,9 +1,16 @@ package com.naturalprogrammer.spring.lemonreactive.security; -import java.io.Serializable; -import java.net.URI; -import java.util.Map; - +import com.naturalprogrammer.spring.lemon.commons.LemonProperties; +import com.naturalprogrammer.spring.lemon.commons.security.BlueTokenService; +import com.naturalprogrammer.spring.lemon.commons.security.LemonPrincipal; +import com.naturalprogrammer.spring.lemon.commons.security.UserDto; +import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; +import com.naturalprogrammer.spring.lemon.commonsreactive.util.LecrUtils; +import com.naturalprogrammer.spring.lemon.exceptions.util.LexUtils; +import com.naturalprogrammer.spring.lemonreactive.LemonReactiveService; +import com.naturalprogrammer.spring.lemonreactive.domain.AbstractMongoUser; +import com.naturalprogrammer.spring.lemonreactive.domain.AbstractMongoUserRepository; +import lombok.AllArgsConstructor; import org.apache.commons.lang3.exception.ExceptionUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -19,21 +26,12 @@ import org.springframework.security.web.server.WebFilterExchange; import org.springframework.security.web.server.authentication.ServerAuthenticationSuccessHandler; import org.springframework.web.server.ServerWebExchange; - -import com.naturalprogrammer.spring.lemon.commons.LemonProperties; -import com.naturalprogrammer.spring.lemon.commons.security.BlueTokenService; -import com.naturalprogrammer.spring.lemon.commons.security.LemonPrincipal; -import com.naturalprogrammer.spring.lemon.commons.security.UserDto; -import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; -import com.naturalprogrammer.spring.lemon.commonsreactive.util.LecrUtils; -import com.naturalprogrammer.spring.lemon.exceptions.util.LexUtils; -import com.naturalprogrammer.spring.lemonreactive.LemonReactiveService; -import com.naturalprogrammer.spring.lemonreactive.domain.AbstractMongoUser; -import com.naturalprogrammer.spring.lemonreactive.domain.AbstractMongoUserRepository; - -import lombok.AllArgsConstructor; import reactor.core.publisher.Mono; +import java.io.Serializable; +import java.net.URI; +import java.util.Map; + /** * Authentication success handler for redirecting the * OAuth2 signed in user to a URL with a short lived auth token @@ -110,7 +108,7 @@ private Mono newUser(String email, String registrationId, Map lemonService.mailForgotPasswordLink(newUser); - } catch (Throwable e) { + } catch (Exception e) { // In case of exception, just log the error and keep silent log.error(ExceptionUtils.getStackTrace(e)); @@ -120,12 +118,10 @@ private Mono newUser(String email, String registrationId, Map private String getAuthToken(UserDto user) { - String shortLivedAuthToken = blueTokenService.createToken( + return blueTokenService.createToken( BlueTokenService.AUTH_AUDIENCE, user.getUsername(), (long) properties.getJwt().getShortLivedMillis()); - - return shortLivedAuthToken; } private String getTargetUrl(ServerWebExchange exchange, String shortLivedAuthToken) { diff --git a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/util/LerUtils.java b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/util/LerUtils.java index 02b705e0..60b4d14c 100644 --- a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/util/LerUtils.java +++ b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/util/LerUtils.java @@ -1,14 +1,13 @@ package com.naturalprogrammer.spring.lemonreactive.util; -import java.io.Serializable; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - import com.naturalprogrammer.spring.lemon.commons.security.LemonTokenService; import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; import com.naturalprogrammer.spring.lemonreactive.domain.AbstractMongoUser; import com.nimbusds.jwt.JWTClaimsSet; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import java.io.Serializable; /** * Useful helper methods diff --git a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/validation/UniqueEmail.java b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/validation/UniqueEmail.java index c29e8631..16f197ce 100644 --- a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/validation/UniqueEmail.java +++ b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/validation/UniqueEmail.java @@ -1,14 +1,13 @@ package com.naturalprogrammer.spring.lemonreactive.validation; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; +import com.naturalprogrammer.spring.lemon.commons.util.UserUtils; import javax.validation.Constraint; import javax.validation.constraints.Email; import javax.validation.constraints.NotBlank; import javax.validation.constraints.Size; - -import com.naturalprogrammer.spring.lemon.commons.util.UserUtils; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; /** * Annotation for unique-email constraint, diff --git a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/validation/UniqueEmailValidator.java b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/validation/UniqueEmailValidator.java index ef6c2e3e..d0f2e15d 100644 --- a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/validation/UniqueEmailValidator.java +++ b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/validation/UniqueEmailValidator.java @@ -1,16 +1,19 @@ package com.naturalprogrammer.spring.lemonreactive.validation; -import static org.springframework.data.mongodb.core.query.Criteria.where; -import static org.springframework.data.mongodb.core.query.Query.query; +import com.naturalprogrammer.spring.lemonreactive.LemonReactiveService; +import lombok.SneakyThrows; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.springframework.data.mongodb.core.ReactiveMongoTemplate; import javax.validation.ConstraintValidator; import javax.validation.ConstraintValidatorContext; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.springframework.data.mongodb.core.MongoTemplate; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.atomic.AtomicBoolean; -import com.naturalprogrammer.spring.lemonreactive.LemonReactiveService; +import static org.springframework.data.mongodb.core.query.Criteria.where; +import static org.springframework.data.mongodb.core.query.Query.query; /** * Validator for unique-email @@ -22,10 +25,10 @@ public class UniqueEmailValidator private static final Log log = LogFactory.getLog(UniqueEmailValidator.class); - private MongoTemplate mongoTemplate; + private ReactiveMongoTemplate mongoTemplate; private Class userClass; - public UniqueEmailValidator(MongoTemplate mongoTemplate, + public UniqueEmailValidator(ReactiveMongoTemplate mongoTemplate, LemonReactiveService lemonReactiveService) { this.mongoTemplate = mongoTemplate; @@ -33,10 +36,22 @@ public UniqueEmailValidator(MongoTemplate mongoTemplate, log.info("Created"); } + @SneakyThrows @Override public boolean isValid(String email, ConstraintValidatorContext context) { - + log.debug("Validating whether email is unique: " + email); - return !mongoTemplate.exists(query(where("email").is(email)), userClass); + + final AtomicBoolean unique = new AtomicBoolean(); + final CountDownLatch latch = new CountDownLatch(1); + + mongoTemplate.exists(query(where("email").is(email)), userClass) + .subscribe(exists -> { + unique.set(!exists); + latch.countDown(); + }); + + latch.await(); + return unique.get(); } } From 47446dfc6dd22efd350cb56f29fa850005d62d66 Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Sun, 19 Jul 2020 07:01:36 +0530 Subject: [PATCH 101/116] JUnit 5 upgrade --- lemon-demo-jpa/pom.xml | 2 +- .../main/resources/config/application-dev.yml | 3 +- .../spring/lemondemo/AbstractMvcTests.java | 7 +- .../spring/lemondemo/BasicMvcTests.java | 10 +- .../spring/lemondemo/ChangeEmailMvcTests.java | 31 ++--- .../lemondemo/ChangePasswordMvcTests.java | 16 +-- .../lemondemo/FetchNewTokenMvcTests.java | 15 +- .../spring/lemondemo/FetchUserMvcTests.java | 14 +- .../lemondemo/ForgotPasswordMvcTests.java | 8 +- .../spring/lemondemo/LoginMvcTests.java | 46 +++---- .../lemondemo/LoginWithNonceMvcTests.java | 130 ------------------ .../lemondemo/RequestEmailChangeMvcTests.java | 29 ++-- .../ResendVerificationMailMvcTests.java | 18 +-- .../lemondemo/ResetPasswordMvcTests.java | 12 +- .../spring/lemondemo/SignupMvcTests.java | 14 +- .../spring/lemondemo/UpdateUserMvcTests.java | 41 +++--- .../lemondemo/VerificationMvcTests.java | 23 ++-- lemon-demo-reactive/pom.xml | 2 +- .../spring/lemondemo/AbstractTests.java | 12 +- .../spring/lemondemo/BasicTests.java | 10 +- .../spring/lemondemo/ChangeEmailTests.java | 23 ++-- .../spring/lemondemo/ChangePasswordTests.java | 16 +-- .../spring/lemondemo/FetchNewTokenTests.java | 15 +- .../spring/lemondemo/FetchUserTests.java | 14 +- .../spring/lemondemo/ForgotPasswordTests.java | 8 +- .../spring/lemondemo/LoginTests.java | 22 +-- .../spring/lemondemo/MyTestUtils.java | 15 +- .../lemondemo/RequestEmailChangeTests.java | 29 ++-- .../ResendVerificationMailTests.java | 18 +-- .../spring/lemondemo/ResetPasswordTests.java | 12 +- .../spring/lemondemo/SignupTests.java | 12 +- .../spring/lemondemo/UpdateUserTests.java | 29 ++-- .../spring/lemondemo/VerificationTests.java | 17 +-- pom.xml | 8 +- spring-lemon-commons-jpa/pom.xml | 2 +- spring-lemon-commons-mongo/pom.xml | 2 +- spring-lemon-commons-reactive/pom.xml | 2 +- spring-lemon-commons-web/pom.xml | 2 +- spring-lemon-commons/pom.xml | 2 +- .../security/LemonJwtServiceTests.java | 102 ++++++++------ spring-lemon-exceptions/pom.xml | 2 +- spring-lemon-jpa/pom.xml | 2 +- spring-lemon-reactive/pom.xml | 2 +- 43 files changed, 330 insertions(+), 469 deletions(-) delete mode 100644 lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/LoginWithNonceMvcTests.java diff --git a/lemon-demo-jpa/pom.xml b/lemon-demo-jpa/pom.xml index 04512799..d2b3b97f 100644 --- a/lemon-demo-jpa/pom.xml +++ b/lemon-demo-jpa/pom.xml @@ -14,7 +14,7 @@ com.naturalprogrammer spring-lemon - 1.0.0.RC4 + 1.0.0.RC5 diff --git a/lemon-demo-jpa/src/main/resources/config/application-dev.yml b/lemon-demo-jpa/src/main/resources/config/application-dev.yml index 40d6a2a6..9c464216 100644 --- a/lemon-demo-jpa/src/main/resources/config/application-dev.yml +++ b/lemon-demo-jpa/src/main/resources/config/application-dev.yml @@ -31,7 +31,8 @@ logging: org.springframework: INFO org.springframework.security.oauth2.client: DEBUG com.naturalprogrammer: DEBUG - #file: D:\\tmp\\dev-log.txt +# file: +# name: D:\\tmp\\dev-log.txt lemon: diff --git a/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/AbstractMvcTests.java b/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/AbstractMvcTests.java index 32d96f66..8660282d 100644 --- a/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/AbstractMvcTests.java +++ b/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/AbstractMvcTests.java @@ -3,8 +3,7 @@ import com.naturalprogrammer.spring.lemon.commons.mail.MailSender; import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; import com.naturalprogrammer.spring.lemondemo.repositories.UserRepository; -import org.junit.Before; -import org.junit.runner.RunWith; +import org.junit.jupiter.api.BeforeEach; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.jdbc.EmbeddedDatabaseConnection; import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase; @@ -14,7 +13,6 @@ import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; import org.springframework.test.context.jdbc.Sql; -import org.springframework.test.context.junit4.SpringRunner; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.MvcResult; @@ -26,7 +24,6 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; -@RunWith(SpringRunner.class) @SpringBootTest({ "logging.level.com.naturalprogrammer=ERROR", // logging.level.root=ERROR does not work: https://stackoverflow.com/questions/49048298/springboottest-not-overriding-logging-level "logging.level.org.springframework=ERROR", @@ -74,7 +71,7 @@ protected String login(String userName, String password) throws Exception { return result.getResponse().getHeader(LecUtils.TOKEN_RESPONSE_HEADER_NAME); } - @Before + @BeforeEach public void baseSetUp() throws Exception { tokens.put(ADMIN_ID, login(ADMIN_EMAIL, ADMIN_PASSWORD)); diff --git a/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/BasicMvcTests.java b/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/BasicMvcTests.java index 182269c6..4ba61043 100644 --- a/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/BasicMvcTests.java +++ b/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/BasicMvcTests.java @@ -1,7 +1,7 @@ package com.naturalprogrammer.spring.lemondemo; import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; -import org.junit.Test; +import org.junit.jupiter.api.Test; import org.springframework.http.HttpHeaders; import org.springframework.test.context.jdbc.Sql; @@ -10,17 +10,17 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; @Sql({"/test-data/initialize.sql", "/test-data/finalize.sql", }) -public class BasicMvcTests extends AbstractMvcTests { +class BasicMvcTests extends AbstractMvcTests { @Test - public void testPing() throws Exception { + void testPing() throws Exception { mvc.perform(get("/api/core/ping")) .andExpect(status().is(204)); } @Test - public void testGetContextLoggedIn() throws Exception { + void testGetContextLoggedIn() throws Exception { mvc.perform(get("/api/core/context") .header(HttpHeaders.AUTHORIZATION, tokens.get(ADMIN_ID))) @@ -33,7 +33,7 @@ public void testGetContextLoggedIn() throws Exception { } @Test - public void testGetContextWithoutLoggedIn() throws Exception { + void testGetContextWithoutLoggedIn() throws Exception { mvc.perform(get("/api/core/context")) .andExpect(status().is(200)) diff --git a/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/ChangeEmailMvcTests.java b/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/ChangeEmailMvcTests.java index 2556321c..03100bcf 100644 --- a/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/ChangeEmailMvcTests.java +++ b/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/ChangeEmailMvcTests.java @@ -3,18 +3,20 @@ import com.naturalprogrammer.spring.lemon.commons.security.GreenTokenService; import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; import com.naturalprogrammer.spring.lemondemo.entities.User; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; +import org.aspectj.lang.annotation.Before; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; import static org.hamcrest.Matchers.containsString; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; -public class ChangeEmailMvcTests extends AbstractMvcTests { +class ChangeEmailMvcTests extends AbstractMvcTests { private static final String NEW_EMAIL = "new.email@example.com"; @@ -23,7 +25,7 @@ public class ChangeEmailMvcTests extends AbstractMvcTests { @Autowired private GreenTokenService greenTokenService; - @Before + @BeforeEach public void setUp() { User user = userRepository.findById(UNVERIFIED_USER_ID).get(); @@ -37,7 +39,7 @@ public void setUp() { } @Test - public void testChangeEmail() throws Exception { + void testChangeEmail() throws Exception { mvc.perform(post("/api/core/users/{id}/email", UNVERIFIED_USER_ID) .param("code", changeEmailCode) @@ -48,8 +50,8 @@ public void testChangeEmail() throws Exception { .andExpect(jsonPath("$.id").value(UNVERIFIED_USER_ID)); User updatedUser = userRepository.findById(UNVERIFIED_USER_ID).get(); - Assert.assertNull(updatedUser.getNewEmail()); - Assert.assertEquals(NEW_EMAIL, updatedUser.getEmail()); + assertNull(updatedUser.getNewEmail()); + assertEquals(NEW_EMAIL, updatedUser.getEmail()); // Shouldn't be able to login with old token mvc.perform(post("/api/core/users/{id}/email", UNVERIFIED_USER_ID) @@ -63,7 +65,7 @@ public void testChangeEmail() throws Exception { * Providing a wrong changeEmailCode shouldn't work. */ @Test - public void testChangeEmailWrongCode() throws Exception { + void testChangeEmailWrongCode() throws Exception { // Blank token mvc.perform(post("/api/core/users/{id}/email", UNVERIFIED_USER_ID) @@ -113,12 +115,11 @@ public void testChangeEmailWrongCode() throws Exception { * Providing an obsolete changeEmailCode shouldn't work. */ @Test - public void testChangeEmailObsoleteCode() throws Exception { + void testChangeEmailObsoleteCode() throws Exception { // credentials updated after the request for email change was made - Thread.sleep(1L); User user = userRepository.findById(UNVERIFIED_USER_ID).get(); - user.setCredentialsUpdatedMillis(System.currentTimeMillis()); + user.setCredentialsUpdatedMillis(System.currentTimeMillis() + 1); userRepository.save(user); // A new auth token is needed, because old one would be obsolete! @@ -134,10 +135,9 @@ public void testChangeEmailObsoleteCode() throws Exception { /** * Trying without having requested first. - * @throws Exception */ @Test - public void testChangeEmailWithoutAnyRequest() throws Exception { + void testChangeEmailWithoutAnyRequest() throws Exception { mvc.perform(post("/api/core/users/{id}/email", USER_ID) .param("code", changeEmailCode) @@ -148,10 +148,9 @@ public void testChangeEmailWithoutAnyRequest() throws Exception { /** * Trying after some user registers the newEmail, leaving it non unique. - * @throws Exception */ @Test - public void testChangeEmailNonUniqueEmail() throws Exception { + void testChangeEmailNonUniqueEmail() throws Exception { // Some other user changed to the same email User user = userRepository.findById(ADMIN_ID).get(); diff --git a/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/ChangePasswordMvcTests.java b/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/ChangePasswordMvcTests.java index 22668e99..454580f2 100644 --- a/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/ChangePasswordMvcTests.java +++ b/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/ChangePasswordMvcTests.java @@ -2,7 +2,7 @@ import com.naturalprogrammer.spring.lemon.commons.domain.ChangePasswordForm; import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; -import org.junit.Test; +import org.junit.jupiter.api.Test; import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; import org.springframework.test.context.jdbc.Sql; @@ -12,7 +12,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; @Sql({"/test-data/initialize.sql", "/test-data/finalize.sql"}) -public class ChangePasswordMvcTests extends AbstractMvcTests { +class ChangePasswordMvcTests extends AbstractMvcTests { private static final String NEW_PASSWORD = "a-new-password"; @@ -30,7 +30,7 @@ private ChangePasswordForm changePasswordForm(String oldPassword) { * A non-admin user should be able to change his password. */ @Test - public void testChangePassword() throws Exception { + void testChangePassword() throws Exception { mvc.perform(post("/api/core/users/{id}/password", UNVERIFIED_USER_ID) .header(HttpHeaders.AUTHORIZATION, tokens.get(UNVERIFIED_USER_ID)) @@ -47,7 +47,7 @@ public void testChangePassword() throws Exception { * An good admin user should be able to change the password of another user. */ @Test - public void testAdminChangePasswordAnotherUser() throws Exception { + void testAdminChangePasswordAnotherUser() throws Exception { mvc.perform(post("/api/core/users/{id}/password", UNVERIFIED_USER_ID) .header(HttpHeaders.AUTHORIZATION, tokens.get(ADMIN_ID)) @@ -64,7 +64,7 @@ public void testAdminChangePasswordAnotherUser() throws Exception { * Providing an unknown id should return 404. */ @Test - public void testChangePasswordUnknownId() throws Exception { + void testChangePasswordUnknownId() throws Exception { mvc.perform(post("/api/core/users/99/password") .header(HttpHeaders.AUTHORIZATION, tokens.get(ADMIN_ID)) @@ -77,7 +77,7 @@ public void testChangePasswordUnknownId() throws Exception { * A non-admin user should not be able to change others' password. */ @Test - public void testChangePasswordAnotherUser() throws Exception { + void testChangePasswordAnotherUser() throws Exception { mvc.perform(post("/api/core/users/{id}/password", UNVERIFIED_USER_ID) .header(HttpHeaders.AUTHORIZATION, tokens.get(USER_ID)) @@ -93,7 +93,7 @@ public void testChangePasswordAnotherUser() throws Exception { * A bad admin user should not be able to change others' password. */ @Test - public void testBadAdminChangePasswordAnotherUser() throws Exception { + void testBadAdminChangePasswordAnotherUser() throws Exception { mvc.perform(post("/api/core/users/{id}/password", UNVERIFIED_USER_ID) .header(HttpHeaders.AUTHORIZATION, tokens.get(UNVERIFIED_ADMIN_ID)) @@ -106,7 +106,7 @@ public void testBadAdminChangePasswordAnotherUser() throws Exception { } @Test - public void testChangePasswordInvalidData() throws Exception { + void testChangePasswordInvalidData() throws Exception { // All fields null mvc.perform(post("/api/core/users/{id}/password", UNVERIFIED_USER_ID) diff --git a/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/FetchNewTokenMvcTests.java b/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/FetchNewTokenMvcTests.java index 4aa283a9..a0d2f40b 100644 --- a/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/FetchNewTokenMvcTests.java +++ b/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/FetchNewTokenMvcTests.java @@ -1,7 +1,7 @@ package com.naturalprogrammer.spring.lemondemo; import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; -import org.junit.Test; +import org.junit.jupiter.api.Test; import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; import org.springframework.test.web.servlet.MvcResult; @@ -12,7 +12,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; -public class FetchNewTokenMvcTests extends AbstractMvcTests { +class FetchNewTokenMvcTests extends AbstractMvcTests { public static class Response { @@ -28,7 +28,7 @@ public void setToken(String token) { } @Test - public void testFetchNewToken() throws Exception { + void testFetchNewToken() throws Exception { MvcResult result = mvc.perform(post("/api/core/fetch-new-auth-token") .header(HttpHeaders.AUTHORIZATION, tokens.get(UNVERIFIED_USER_ID)) @@ -42,7 +42,7 @@ public void testFetchNewToken() throws Exception { } @Test - public void testFetchNewTokenExpiration() throws Exception { + void testFetchNewTokenExpiration() throws Exception { MvcResult result = mvc.perform(post("/api/core/fetch-new-auth-token") .header(HttpHeaders.AUTHORIZATION, tokens.get(UNVERIFIED_USER_ID)) @@ -54,16 +54,15 @@ public void testFetchNewTokenExpiration() throws Exception { Response response = LecUtils.fromJson(result.getResponse().getContentAsString(), Response.class); ensureTokenWorks(response.getToken()); - Thread.sleep(1001L); + Thread.sleep(1001L); // Let more then a second pass mvc.perform(get("/api/core/context") .header(HttpHeaders.AUTHORIZATION, LecUtils.TOKEN_PREFIX + response.getToken())) .andExpect(status().is(401)); - } @Test - public void testFetchNewTokenByAdminForAnotherUser() throws Exception { + void testFetchNewTokenByAdminForAnotherUser() throws Exception { MvcResult result = mvc.perform(post("/api/core/fetch-new-auth-token") .header(HttpHeaders.AUTHORIZATION, tokens.get(ADMIN_ID)) @@ -77,7 +76,7 @@ public void testFetchNewTokenByAdminForAnotherUser() throws Exception { } @Test - public void testFetchNewTokenByNonAdminForAnotherUser() throws Exception { + void testFetchNewTokenByNonAdminForAnotherUser() throws Exception { mvc.perform(post("/api/core/fetch-new-auth-token") .header(HttpHeaders.AUTHORIZATION, tokens.get(UNVERIFIED_USER_ID)) diff --git a/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/FetchUserMvcTests.java b/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/FetchUserMvcTests.java index 6f875792..e68e6560 100644 --- a/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/FetchUserMvcTests.java +++ b/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/FetchUserMvcTests.java @@ -1,6 +1,6 @@ package com.naturalprogrammer.spring.lemondemo; -import org.junit.Test; +import org.junit.jupiter.api.Test; import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; import org.springframework.test.context.jdbc.Sql; @@ -11,10 +11,10 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @Sql({"/test-data/initialize.sql", "/test-data/finalize.sql"}) -public class FetchUserMvcTests extends AbstractMvcTests { +class FetchUserMvcTests extends AbstractMvcTests { @Test - public void testFetchUserById() throws Exception { + void testFetchUserById() throws Exception { mvc.perform(get("/api/core/users/{id}", ADMIN_ID)) .andExpect(status().is(200)) @@ -26,7 +26,7 @@ public void testFetchUserById() throws Exception { } @Test - public void testFetchUserByIdLoggedIn() throws Exception { + void testFetchUserByIdLoggedIn() throws Exception { // Same user logged in mvc.perform(get("/api/core/users/{id}", ADMIN_ID) @@ -54,14 +54,14 @@ public void testFetchUserByIdLoggedIn() throws Exception { } @Test - public void testFetchNonExistingUserById() throws Exception { + void testFetchNonExistingUserById() throws Exception { mvc.perform(get("/api/core/users/99")) .andExpect(status().is(404)); } @Test - public void testFetchUserByEmail() throws Exception { + void testFetchUserByEmail() throws Exception { mvc.perform(post("/api/core/users/fetch-by-email") .param("email", ADMIN_EMAIL) @@ -74,7 +74,7 @@ public void testFetchUserByEmail() throws Exception { } @Test - public void testFetchUserByInvalidEmail() throws Exception { + void testFetchUserByInvalidEmail() throws Exception { // email does not exist mvc.perform(post("/api/core/users/fetch-by-email") diff --git a/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/ForgotPasswordMvcTests.java b/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/ForgotPasswordMvcTests.java index 5eef92fe..2ea53bc5 100644 --- a/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/ForgotPasswordMvcTests.java +++ b/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/ForgotPasswordMvcTests.java @@ -1,6 +1,6 @@ package com.naturalprogrammer.spring.lemondemo; -import org.junit.Test; +import org.junit.jupiter.api.Test; import org.springframework.http.MediaType; import static org.mockito.ArgumentMatchers.any; @@ -9,10 +9,10 @@ import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; -public class ForgotPasswordMvcTests extends AbstractMvcTests { +class ForgotPasswordMvcTests extends AbstractMvcTests { @Test - public void testForgotPassword() throws Exception { + void testForgotPassword() throws Exception { mvc.perform(post("/api/core/forgot-password") .param("email", ADMIN_EMAIL) @@ -23,7 +23,7 @@ public void testForgotPassword() throws Exception { } @Test - public void testForgotPasswordInvalidEmail() throws Exception { + void testForgotPasswordInvalidEmail() throws Exception { // Unknown email mvc.perform(post("/api/core/forgot-password") diff --git a/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/LoginMvcTests.java b/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/LoginMvcTests.java index 587b5662..22c47347 100644 --- a/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/LoginMvcTests.java +++ b/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/LoginMvcTests.java @@ -2,7 +2,7 @@ import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; import com.naturalprogrammer.spring.lemondemo.entities.User; -import org.junit.Test; +import org.junit.jupiter.api.Test; import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; import org.springframework.test.context.jdbc.Sql; @@ -15,10 +15,10 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; @Sql({"/test-data/initialize.sql", "/test-data/finalize.sql"}) -public class LoginMvcTests extends AbstractMvcTests { +class LoginMvcTests extends AbstractMvcTests { @Test - public void testLogin() throws Exception { + void testLogin() throws Exception { mvc.perform(post("/api/core/login") .param("username", ADMIN_EMAIL) @@ -40,20 +40,21 @@ public void testLogin() throws Exception { } @Test - public void testLoginTokenExpiry() throws Exception { + void testLoginTokenExpiry() throws Exception { -// // Test that default token does not expire before 10 days -// Thread.sleep(1001L); -// mvc.perform(get("/api/core/ping") -// .header(LemonSecurityConfig.TOKEN_REQUEST_HEADER_NAME, tokens.get(ADMIN_ID))) -// .andExpect(status().is(204)); + // Test that default token works (does not expire before 10 days) + mvc.perform(get("/api/core/ping") + .header(HttpHeaders.AUTHORIZATION, tokens.get(ADMIN_ID))) + .andExpect(status().is(204)); - // Test that a 500ms token does not expire before 500ms - String token = login(ADMIN_EMAIL, ADMIN_PASSWORD, 500L); -// mvc.perform(get("/api/core/ping") -// .header(LemonSecurityConfig.TOKEN_REQUEST_HEADER_NAME, token)) -// .andExpect(status().is(204)); - // but, does expire after 500ms + // Test that a 5000ms token does not expire before 5000ms + String token = login(ADMIN_EMAIL, ADMIN_PASSWORD, 5000L); + mvc.perform(get("/api/core/ping") + .header(HttpHeaders.AUTHORIZATION, token)) + .andExpect(status().is(204)); + + // Test that a 500ms token expires after 500ms + token = login(ADMIN_EMAIL, ADMIN_PASSWORD, 500L); Thread.sleep(501L); mvc.perform(get("/api/core/ping") .header(HttpHeaders.AUTHORIZATION, token)) @@ -64,12 +65,11 @@ public void testLoginTokenExpiry() throws Exception { * Token won't work if the credentials of the user gets updated afterwards */ @Test - public void testObsoleteToken() throws Exception { + void testObsoleteToken() throws Exception { // credentials updated - // Thread.sleep(1001L); User user = userRepository.findById(ADMIN_ID).get(); - user.setCredentialsUpdatedMillis(System.currentTimeMillis()); + user.setCredentialsUpdatedMillis(System.currentTimeMillis() + 1); userRepository.save(user); mvc.perform(get("/api/core/ping") @@ -78,7 +78,7 @@ public void testObsoleteToken() throws Exception { } @Test - public void testLoginWrongPassword() throws Exception { + void testLoginWrongPassword() throws Exception { mvc.perform(post("/api/core/login") .param("username", ADMIN_EMAIL) @@ -88,7 +88,7 @@ public void testLoginWrongPassword() throws Exception { } @Test - public void testLoginBlankPassword() throws Exception { + void testLoginBlankPassword() throws Exception { mvc.perform(post("/api/core/login") .param("username", ADMIN_EMAIL) @@ -98,7 +98,7 @@ public void testLoginBlankPassword() throws Exception { } @Test - public void testTokenLogin() throws Exception { + void testTokenLogin() throws Exception { mvc.perform(get("/api/core/context") .header(HttpHeaders.AUTHORIZATION, tokens.get(ADMIN_ID))) @@ -107,7 +107,7 @@ public void testTokenLogin() throws Exception { } @Test - public void testTokenLoginWrongToken() throws Exception { + void testTokenLoginWrongToken() throws Exception { mvc.perform(get("/api/core/context") .header(HttpHeaders.AUTHORIZATION, "Bearer a-wrong-token")) @@ -115,7 +115,7 @@ public void testTokenLoginWrongToken() throws Exception { } @Test - public void testLogout() throws Exception { + void testLogout() throws Exception { mvc.perform(post("/logout")) .andExpect(status().is(404)); diff --git a/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/LoginWithNonceMvcTests.java b/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/LoginWithNonceMvcTests.java deleted file mode 100644 index 141d328d..00000000 --- a/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/LoginWithNonceMvcTests.java +++ /dev/null @@ -1,130 +0,0 @@ -//package com.naturalprogrammer.spring.lemondemo; -// -//import static org.hamcrest.Matchers.containsString; -//import static org.hamcrest.Matchers.hasItems; -//import static org.hamcrest.Matchers.hasSize; -//import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; -//import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; -//import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header; -//import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; -//import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; -// -//import org.junit.Assert; -//import org.junit.Before; -//import org.junit.Test; -//import org.springframework.http.MediaType; -//import org.springframework.test.web.servlet.MvcResult; -// -//import com.fasterxml.jackson.core.JsonProcessingException; -//import com.naturalprogrammer.spring.lemon.forms.NonceForm; -//import com.naturalprogrammer.spring.lemon.security.LemonSecurityConfig; -//import com.naturalprogrammer.spring.lemon.util.LemonUtils; -//import com.naturalprogrammer.spring.lemondemo.entities.User; -// -//public class LoginWithNonceMvcTests extends AbstractMvcTests { -// -// private static final String NONCE = LemonUtils.uid(); -// -// private NonceForm form(Long jwtExpirationMillis) { -// -// NonceForm nonceForm = new NonceForm<>(); -// nonceForm.setNonce(NONCE); -// nonceForm.setUserId(UNVERIFIED_USER_ID); -// nonceForm.setExpirationMillis(jwtExpirationMillis); -// -// return nonceForm; -// } -// -// @Before -// public void setUp() { -// -// User user = userRepository.findById(UNVERIFIED_USER_ID).get(); -// user.setNonce(NONCE); -// userRepository.save(user); -// } -// -// @Test -// public void testLoginWithNonce() throws Exception { -// -// String token = loginWithNonce(null); -// -// User user = userRepository.findById(UNVERIFIED_USER_ID).get(); -// Assert.assertNull(user.getNonce()); -// -// ensureTokenWorks(token); -// -// // Retry should fail -// mvc.perform(post("/api/core/login-with-nonce") -// .contentType(MediaType.APPLICATION_JSON) -// .content(LemonUtils.toJson(form(null)))) -// .andExpect(status().is(401)); -// } -// -// @Test -// public void testLoginWithNonceExpiryOk() throws Exception { -// -// String token = loginWithNonce(1000L); -// ensureTokenWorks(token); -// } -// -// @Test -// public void testLoginWithNonceExpiryShouldFail() throws Exception { -// -// String token = loginWithNonce(100L); -// Thread.sleep(101L); -// -// mvc.perform(get("/api/core/context") -// .header(LemonSecurityConfig.TOKEN_REQUEST_HEADER_NAME, token)) -// .andExpect(status().is(401)); -// } -// -// @Test -// public void testLoginWithNonceInvalidData() throws Exception { -// -// mvc.perform(post("/api/core/login-with-nonce") -// .contentType(MediaType.APPLICATION_JSON) -// .content(LemonUtils.toJson(new NonceForm()))) -// .andExpect(status().is(422)) -// .andExpect(jsonPath("$.errors[*].field").value(hasSize(2))) -// .andExpect(jsonPath("$.errors[*].field").value(hasItems( -// "nonce.userId", -// "nonce.nonce"))); -// } -// -// @Test -// public void testLoginWithNonceUnknownUser() throws Exception { -// -// NonceForm form = form(null); -// form.setUserId(99L); -// -// mvc.perform(post("/api/core/login-with-nonce") -// .contentType(MediaType.APPLICATION_JSON) -// .content(LemonUtils.toJson(form))) -// .andExpect(status().is(404)); -// } -// -// @Test -// public void testLoginWithWrongNonce() throws Exception { -// -// NonceForm form = form(null); -// form.setNonce("wrong-nonce"); -// -// mvc.perform(post("/api/core/login-with-nonce") -// .contentType(MediaType.APPLICATION_JSON) -// .content(LemonUtils.toJson(form))) -// .andExpect(status().is(401)); -// } -// -// private String loginWithNonce(Long jwtExpirationMillis) throws JsonProcessingException, Exception { -// -// MvcResult result = mvc.perform(post("/api/core/login-with-nonce") -// .contentType(MediaType.APPLICATION_JSON) -// .content(LemonUtils.toJson(form(jwtExpirationMillis)))) -// .andExpect(status().is(200)) -// .andExpect(header().string(LemonSecurityConfig.TOKEN_RESPONSE_HEADER_NAME, containsString("."))) -// .andExpect(jsonPath("$.id").value(UNVERIFIED_USER_ID)) -// .andReturn(); -// -// return result.getResponse().getHeader(LemonSecurityConfig.TOKEN_RESPONSE_HEADER_NAME); -// } -//} diff --git a/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/RequestEmailChangeMvcTests.java b/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/RequestEmailChangeMvcTests.java index 89cf5482..38f7fa75 100644 --- a/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/RequestEmailChangeMvcTests.java +++ b/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/RequestEmailChangeMvcTests.java @@ -3,13 +3,14 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; import com.naturalprogrammer.spring.lemondemo.entities.User; -import org.junit.Assert; -import org.junit.Test; +import org.junit.jupiter.api.Test; import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; import static org.hamcrest.Matchers.hasItems; import static org.hamcrest.Matchers.hasSize; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; @@ -17,7 +18,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; -public class RequestEmailChangeMvcTests extends AbstractMvcTests { +class RequestEmailChangeMvcTests extends AbstractMvcTests { private static final String NEW_EMAIL = "new.email@example.com"; @@ -31,7 +32,7 @@ private User form() { } @Test - public void testRequestEmailChange() throws Exception { + void testRequestEmailChange() throws Exception { mvc.perform(post("/api/core/users/{id}/email-change-request", UNVERIFIED_USER_ID) .contentType(MediaType.APPLICATION_JSON) @@ -42,15 +43,15 @@ public void testRequestEmailChange() throws Exception { verify(mailSender).send(any()); User updatedUser = userRepository.findById(UNVERIFIED_USER_ID).get(); - Assert.assertEquals(NEW_EMAIL, updatedUser.getNewEmail()); - Assert.assertEquals(UNVERIFIED_USER_EMAIL, updatedUser.getEmail()); + assertEquals(NEW_EMAIL, updatedUser.getNewEmail()); + assertEquals(UNVERIFIED_USER_EMAIL, updatedUser.getEmail()); } /** * A good admin should be able to request changing email of another user. */ @Test - public void testGoodAdminRequestEmailChange() throws Exception { + void testGoodAdminRequestEmailChange() throws Exception { mvc.perform(post("/api/core/users/{id}/email-change-request", UNVERIFIED_USER_ID) .contentType(MediaType.APPLICATION_JSON) @@ -59,14 +60,14 @@ public void testGoodAdminRequestEmailChange() throws Exception { .andExpect(status().is(204)); User updatedUser = userRepository.findById(UNVERIFIED_USER_ID).get(); - Assert.assertEquals(NEW_EMAIL, updatedUser.getNewEmail()); + assertEquals(NEW_EMAIL, updatedUser.getNewEmail()); } /** * A request changing email of unknown user. */ @Test - public void testRequestEmailChangeUnknownUser() throws Exception { + void testRequestEmailChangeUnknownUser() throws Exception { mvc.perform(post("/api/core/users/99/email-change-request") .contentType(MediaType.APPLICATION_JSON) @@ -82,7 +83,7 @@ public void testRequestEmailChangeUnknownUser() throws Exception { * the email id of another user */ @Test - public void testNonAdminRequestEmailChangeAnotherUser() throws Exception { + void testNonAdminRequestEmailChangeAnotherUser() throws Exception { mvc.perform(post("/api/core/users/{id}/email-change-request", ADMIN_ID) .contentType(MediaType.APPLICATION_JSON) @@ -93,7 +94,7 @@ public void testNonAdminRequestEmailChangeAnotherUser() throws Exception { verify(mailSender, never()).send(any()); User updatedUser = userRepository.findById(UNVERIFIED_USER_ID).get(); - Assert.assertNull(updatedUser.getNewEmail()); + assertNull(updatedUser.getNewEmail()); } /** @@ -101,7 +102,7 @@ public void testNonAdminRequestEmailChangeAnotherUser() throws Exception { * of another user */ @Test - public void testBadAdminRequestEmailChangeAnotherUser() throws Exception { + void testBadAdminRequestEmailChangeAnotherUser() throws Exception { mvc.perform(post("/api/core/users/{id}/email-change-request", ADMIN_ID) .contentType(MediaType.APPLICATION_JSON) @@ -114,11 +115,9 @@ public void testBadAdminRequestEmailChangeAnotherUser() throws Exception { /** * Trying with invalid data. - * @throws Exception - * @throws JsonProcessingException */ @Test - public void tryingWithInvalidData() throws JsonProcessingException, Exception { + void tryingWithInvalidData() throws JsonProcessingException, Exception { // try with null newEmail and password mvc.perform(post("/api/core/users/{id}/email-change-request", UNVERIFIED_USER_ID) diff --git a/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/ResendVerificationMailMvcTests.java b/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/ResendVerificationMailMvcTests.java index e9645d86..a20a32f5 100644 --- a/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/ResendVerificationMailMvcTests.java +++ b/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/ResendVerificationMailMvcTests.java @@ -1,6 +1,6 @@ package com.naturalprogrammer.spring.lemondemo; -import org.junit.Test; +import org.junit.jupiter.api.Test; import org.springframework.http.HttpHeaders; import static org.mockito.ArgumentMatchers.any; @@ -9,10 +9,10 @@ import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; -public class ResendVerificationMailMvcTests extends AbstractMvcTests { +class ResendVerificationMailMvcTests extends AbstractMvcTests { @Test - public void testResendVerificationMail() throws Exception { + void testResendVerificationMail() throws Exception { mvc.perform(post("/api/core/users/{id}/resend-verification-mail", UNVERIFIED_USER_ID) .header(HttpHeaders.AUTHORIZATION, tokens.get(UNVERIFIED_USER_ID))) @@ -22,7 +22,7 @@ public void testResendVerificationMail() throws Exception { } @Test - public void testAdminResendVerificationMailOtherUser() throws Exception { + void testAdminResendVerificationMailOtherUser() throws Exception { mvc.perform(post("/api/core/users/{id}/resend-verification-mail", UNVERIFIED_USER_ID) .header(HttpHeaders.AUTHORIZATION, tokens.get(ADMIN_ID))) @@ -30,7 +30,7 @@ public void testAdminResendVerificationMailOtherUser() throws Exception { } @Test - public void testBadAdminResendVerificationMailOtherUser() throws Exception { + void testBadAdminResendVerificationMailOtherUser() throws Exception { mvc.perform(post("/api/core/users/{id}/resend-verification-mail", UNVERIFIED_USER_ID) .header(HttpHeaders.AUTHORIZATION, tokens.get(UNVERIFIED_ADMIN_ID))) @@ -44,7 +44,7 @@ public void testBadAdminResendVerificationMailOtherUser() throws Exception { } @Test - public void testResendVerificationMailUnauthenticated() throws Exception { + void testResendVerificationMailUnauthenticated() throws Exception { mvc.perform(post("/api/core/users/{id}/resend-verification-mail", UNVERIFIED_USER_ID)) .andExpect(status().is(403)); @@ -53,7 +53,7 @@ public void testResendVerificationMailUnauthenticated() throws Exception { } @Test - public void testResendVerificationMailAlreadyVerified() throws Exception { + void testResendVerificationMailAlreadyVerified() throws Exception { mvc.perform(post("/api/core/users/{id}/resend-verification-mail", USER_ID) .header(HttpHeaders.AUTHORIZATION, tokens.get(USER_ID))) @@ -63,7 +63,7 @@ public void testResendVerificationMailAlreadyVerified() throws Exception { } @Test - public void testResendVerificationMailOtherUser() throws Exception { + void testResendVerificationMailOtherUser() throws Exception { mvc.perform(post("/api/core/users/{id}/resend-verification-mail", UNVERIFIED_USER_ID) .header(HttpHeaders.AUTHORIZATION, tokens.get(USER_ID))) @@ -73,7 +73,7 @@ public void testResendVerificationMailOtherUser() throws Exception { } @Test - public void testResendVerificationMailNonExistingUser() throws Exception { + void testResendVerificationMailNonExistingUser() throws Exception { mvc.perform(post("/api/core/users/99/resend-verification-mail") .header(HttpHeaders.AUTHORIZATION, tokens.get(ADMIN_ID))) diff --git a/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/ResetPasswordMvcTests.java b/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/ResetPasswordMvcTests.java index 48abfe62..efee8510 100644 --- a/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/ResetPasswordMvcTests.java +++ b/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/ResetPasswordMvcTests.java @@ -4,8 +4,8 @@ import com.naturalprogrammer.spring.lemon.commons.domain.ResetPasswordForm; import com.naturalprogrammer.spring.lemon.commons.security.GreenTokenService; import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; -import org.junit.Before; -import org.junit.Test; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.MediaType; @@ -13,14 +13,14 @@ import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; -public class ResetPasswordMvcTests extends AbstractMvcTests { +class ResetPasswordMvcTests extends AbstractMvcTests { private String forgotPasswordCode; @Autowired private GreenTokenService greenTokenService; - @Before + @BeforeEach public void setUp() { forgotPasswordCode = greenTokenService.createToken( @@ -29,7 +29,7 @@ public void setUp() { } @Test - public void testResetPassword() throws Exception { + void testResetPassword() throws Exception { final String NEW_PASSWORD = "newPassword!"; @@ -53,7 +53,7 @@ public void testResetPassword() throws Exception { } @Test - public void testResetPasswordInvalidData() throws Exception { + void testResetPasswordInvalidData() throws Exception { // Wrong code mvc.perform(post("/api/core/reset-password") diff --git a/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/SignupMvcTests.java b/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/SignupMvcTests.java index d2fdb4e8..6dc4f511 100644 --- a/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/SignupMvcTests.java +++ b/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/SignupMvcTests.java @@ -2,12 +2,12 @@ import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; import com.naturalprogrammer.spring.lemondemo.entities.User; -import org.junit.Assert; -import org.junit.Test; +import org.junit.jupiter.api.Test; import org.springframework.http.MediaType; import org.springframework.test.context.jdbc.Sql; import static org.hamcrest.Matchers.*; +import static org.junit.jupiter.api.Assertions.assertNotEquals; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; @@ -15,10 +15,10 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; @Sql({"/test-data/initialize.sql", "/test-data/finalize.sql"}) -public class SignupMvcTests extends AbstractMvcTests { +class SignupMvcTests extends AbstractMvcTests { @Test - public void testSignupWithInvalidData() throws Exception { + void testSignupWithInvalidData() throws Exception { User invalidUser = new User("abc", "user1", null); @@ -44,7 +44,7 @@ public void testSignupWithInvalidData() throws Exception { } @Test - public void testSignup() throws Exception { + void testSignup() throws Exception { User user = new User("user.foo@example.com", "user123", "User Foo"); @@ -68,11 +68,11 @@ public void testSignup() throws Exception { verify(mailSender).send(any()); // Ensure that password got encrypted - Assert.assertNotEquals("user123", userRepository.findByEmail("user.foo@example.com").get().getPassword()); + assertNotEquals("user123", userRepository.findByEmail("user.foo@example.com").get().getPassword()); } @Test - public void testSignupDuplicateEmail() throws Exception { + void testSignupDuplicateEmail() throws Exception { User user = new User("user@example.com", "user123", "User"); diff --git a/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/UpdateUserMvcTests.java b/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/UpdateUserMvcTests.java index 9b1b7fbf..69919bdf 100644 --- a/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/UpdateUserMvcTests.java +++ b/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/UpdateUserMvcTests.java @@ -3,8 +3,7 @@ import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; import com.naturalprogrammer.spring.lemon.commons.util.UserUtils; import com.naturalprogrammer.spring.lemondemo.entities.User; -import org.junit.Assert; -import org.junit.Test; +import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Value; import org.springframework.core.io.Resource; import org.springframework.http.HttpHeaders; @@ -15,11 +14,13 @@ import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.hasSize; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.patch; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; @Sql({"/test-data/initialize.sql", "/test-data/finalize.sql"}) -public class UpdateUserMvcTests extends AbstractMvcTests { +class UpdateUserMvcTests extends AbstractMvcTests { private static final String UPDATED_NAME = "Edited name"; @@ -53,10 +54,9 @@ public void setUserPatchLongName(Resource patch) throws IOException { * but changes in roles should be skipped. * The name of security principal object should also * change in the process. - * @throws Exception */ @Test - public void testUpdateSelf() throws Exception { + void testUpdateSelf() throws Exception { mvc.perform(patch("/api/core/users/{id}", UNVERIFIED_USER_ID) .contentType(MediaType.APPLICATION_JSON) @@ -72,10 +72,10 @@ public void testUpdateSelf() throws Exception { User user = userRepository.findById(UNVERIFIED_USER_ID).get(); // Ensure that data changed properly - Assert.assertEquals(UNVERIFIED_USER_EMAIL, user.getEmail()); - Assert.assertEquals(1, user.getRoles().size()); - Assert.assertTrue(user.getRoles().contains(UserUtils.Role.UNVERIFIED)); - Assert.assertEquals(2L, user.getVersion().longValue()); + assertEquals(UNVERIFIED_USER_EMAIL, user.getEmail()); + assertEquals(1, user.getRoles().size()); + assertTrue(user.getRoles().contains(UserUtils.Role.UNVERIFIED)); + assertEquals(2L, user.getVersion().longValue()); // Version mismatch mvc.perform(patch("/api/core/users/{id}", UNVERIFIED_USER_ID) @@ -90,10 +90,9 @@ public void testUpdateSelf() throws Exception { * The name of security principal object should NOT change in the process, * and the verification code should get set/unset on addition/deletion of * the UNVERIFIED role. - * @throws Exception */ @Test - public void testGoodAdminCanUpdateOther() throws Exception { + void testGoodAdminCanUpdateOther() throws Exception { mvc.perform(patch("/api/core/users/{id}", UNVERIFIED_USER_ID) .contentType(MediaType.APPLICATION_JSON) @@ -110,16 +109,16 @@ public void testGoodAdminCanUpdateOther() throws Exception { User user = userRepository.findById(UNVERIFIED_USER_ID).get(); // Ensure that data changed properly - Assert.assertEquals(UNVERIFIED_USER_EMAIL, user.getEmail()); - Assert.assertEquals(1, user.getRoles().size()); - Assert.assertTrue(user.getRoles().contains(UserUtils.Role.ADMIN)); + assertEquals(UNVERIFIED_USER_EMAIL, user.getEmail()); + assertEquals(1, user.getRoles().size()); + assertTrue(user.getRoles().contains(UserUtils.Role.ADMIN)); } /** * Providing an unknown id should return 404. */ @Test - public void testUpdateUnknownId() throws Exception { + void testUpdateUnknownId() throws Exception { mvc.perform(patch("/api/core/users/{id}", 99) .contentType(MediaType.APPLICATION_JSON) @@ -130,10 +129,9 @@ public void testUpdateUnknownId() throws Exception { /** * A non-admin trying to update the name and roles of another user should throw exception - * @throws Exception */ @Test - public void testUpdateAnotherUser() throws Exception { + void testUpdateAnotherUser() throws Exception { mvc.perform(patch("/api/core/users/{id}", ADMIN_ID) .contentType(MediaType.APPLICATION_JSON) @@ -144,10 +142,9 @@ public void testUpdateAnotherUser() throws Exception { /** * A bad ADMIN trying to update the name and roles of another user should throw exception - * @throws Exception */ @Test - public void testBadAdminUpdateAnotherUser() throws Exception { + void testBadAdminUpdateAnotherUser() throws Exception { mvc.perform(patch("/api/core/users/{id}", UNVERIFIED_USER_ID) .contentType(MediaType.APPLICATION_JSON) @@ -164,10 +161,9 @@ public void testBadAdminUpdateAnotherUser() throws Exception { /** * A good ADMIN should not be able to change his own roles - * @throws Exception */ @Test - public void goodAdminCanNotUpdateSelfRoles() throws Exception { + void goodAdminCanNotUpdateSelfRoles() throws Exception { mvc.perform(patch("/api/core/users/{id}", ADMIN_ID) .contentType(MediaType.APPLICATION_JSON) @@ -181,10 +177,9 @@ public void goodAdminCanNotUpdateSelfRoles() throws Exception { /** * Invalid name - * @throws Exception */ @Test - public void testUpdateUserInvalidNewName() throws Exception { + void testUpdateUserInvalidNewName() throws Exception { // Null name mvc.perform(patch("/api/core/users/{id}", UNVERIFIED_USER_ID) diff --git a/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/VerificationMvcTests.java b/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/VerificationMvcTests.java index fb7a69f1..00224391 100644 --- a/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/VerificationMvcTests.java +++ b/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/VerificationMvcTests.java @@ -2,9 +2,11 @@ import com.naturalprogrammer.spring.lemon.commons.security.GreenTokenService; import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; +import com.naturalprogrammer.spring.lemon.exceptions.util.LexUtils; import com.naturalprogrammer.spring.lemondemo.entities.User; -import org.junit.Before; -import org.junit.Test; +import org.aspectj.lang.annotation.Before; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.MediaType; @@ -13,14 +15,14 @@ import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; -public class VerificationMvcTests extends AbstractMvcTests { +class VerificationMvcTests extends AbstractMvcTests { private String verificationCode; @Autowired private GreenTokenService greenTokenService; - @Before + @BeforeEach public void setUp() { verificationCode = greenTokenService.createToken(GreenTokenService.VERIFY_AUDIENCE, @@ -29,7 +31,7 @@ public void setUp() { } @Test - public void testEmailVerification() throws Exception { + void testEmailVerification() throws Exception { mvc.perform(post("/api/core/users/{userId}/verification", UNVERIFIED_USER_ID) .param("code", verificationCode) @@ -49,7 +51,7 @@ public void testEmailVerification() throws Exception { } @Test - public void testEmailVerificationNonExistingUser() throws Exception { + void testEmailVerificationNonExistingUser() throws Exception { mvc.perform(post("/api/core/users/99/verification") .param("code", verificationCode) @@ -58,7 +60,7 @@ public void testEmailVerificationNonExistingUser() throws Exception { } @Test - public void testEmailVerificationWrongToken() throws Exception { + void testEmailVerificationWrongToken() throws Exception { // null token mvc.perform(post("/api/core/users/{userId}/verification", UNVERIFIED_USER_ID) @@ -101,12 +103,11 @@ public void testEmailVerificationWrongToken() throws Exception { } @Test - public void testEmailVerificationAfterCredentialsUpdate() throws Exception { + void testEmailVerificationAfterCredentialsUpdate() throws Exception { // Credentials updated after the verification token is issued - Thread.sleep(1L); - User user = userRepository.findById(UNVERIFIED_USER_ID).get(); - user.setCredentialsUpdatedMillis(System.currentTimeMillis()); + User user = userRepository.findById(UNVERIFIED_USER_ID).orElseThrow(LexUtils.notFoundSupplier()); + user.setCredentialsUpdatedMillis(System.currentTimeMillis() + 1); userRepository.save(user); mvc.perform(post("/api/core/users/{userId}/verification", UNVERIFIED_USER_ID) diff --git a/lemon-demo-reactive/pom.xml b/lemon-demo-reactive/pom.xml index df4c895a..85ae39ce 100644 --- a/lemon-demo-reactive/pom.xml +++ b/lemon-demo-reactive/pom.xml @@ -13,7 +13,7 @@ com.naturalprogrammer spring-lemon - 1.0.0.RC4 + 1.0.0.RC5 diff --git a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/AbstractTests.java b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/AbstractTests.java index 47cc68eb..f6d245d2 100644 --- a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/AbstractTests.java +++ b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/AbstractTests.java @@ -3,22 +3,19 @@ import com.naturalprogrammer.spring.lemon.commons.mail.MailSender; import com.naturalprogrammer.spring.lemondemo.dto.TestErrorResponse; import com.naturalprogrammer.spring.lemondemo.dto.TestLemonFieldError; -import org.junit.Before; -import org.junit.runner.RunWith; +import org.junit.jupiter.api.BeforeEach; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.data.mongodb.core.ReactiveMongoTemplate; -import org.springframework.test.context.junit4.SpringRunner; import org.springframework.test.web.reactive.server.EntityExchangeResult; import java.util.Arrays; import java.util.stream.Collectors; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; -@RunWith(SpringRunner.class) @SpringBootTest({ "logging.level.com.naturalprogrammer=ERROR", // logging.level.root=ERROR does not work: https://stackoverflow.com/questions/49048298/springboottest-not-overriding-logging-level "logging.level.org.springframework=ERROR", @@ -36,12 +33,11 @@ public abstract class AbstractTests { @MockBean protected MailSender mailSender; - @Before + @BeforeEach public void initialize() { testUtils.initDatabase(); } - protected void assertErrors(EntityExchangeResult errorResponseResult, String... fields) { diff --git a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/BasicTests.java b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/BasicTests.java index 8c86eb2a..fc934cd0 100644 --- a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/BasicTests.java +++ b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/BasicTests.java @@ -1,15 +1,15 @@ package com.naturalprogrammer.spring.lemondemo; import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; -import org.junit.Test; +import org.junit.jupiter.api.Test; import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.*; import static com.naturalprogrammer.spring.lemondemo.controllers.MyController.BASE_URI; -public class BasicTests extends AbstractTests { +class BasicTests extends AbstractTests { @Test - public void testPing() throws Exception { + void testPing() throws Exception { CLIENT.get() .uri(BASE_URI + "/ping") @@ -19,7 +19,7 @@ public void testPing() throws Exception { } @Test - public void testGetContextLoggedIn() throws Exception { + void testGetContextLoggedIn() throws Exception { testUtils.contextResponse(TOKENS.get(ADMIN_ID)) .expectHeader().exists(LecUtils.TOKEN_RESPONSE_HEADER_NAME) @@ -31,7 +31,7 @@ public void testGetContextLoggedIn() throws Exception { } @Test - public void testGetContextWithoutLoggedIn() throws Exception { + void testGetContextWithoutLoggedIn() throws Exception { CLIENT.get() .uri(BASE_URI + "/context") diff --git a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/ChangeEmailTests.java b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/ChangeEmailTests.java index 254e8b12..07dae7eb 100644 --- a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/ChangeEmailTests.java +++ b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/ChangeEmailTests.java @@ -3,9 +3,8 @@ import com.naturalprogrammer.spring.lemon.commons.security.GreenTokenService; import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; import com.naturalprogrammer.spring.lemondemo.domain.User; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; @@ -13,6 +12,8 @@ import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.*; import static com.naturalprogrammer.spring.lemondemo.controllers.MyController.BASE_URI; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; import static org.springframework.web.reactive.function.BodyInserters.fromFormData; public class ChangeEmailTests extends AbstractTests { @@ -24,10 +25,11 @@ public class ChangeEmailTests extends AbstractTests { @Autowired private GreenTokenService greenTokenService; - @Before + @BeforeEach public void setUp() { User user = mongoTemplate.findById(UNVERIFIED_USER_ID, User.class).block(); + assert user != null; user.setNewEmail(NEW_EMAIL); mongoTemplate.save(user).block(); @@ -38,7 +40,7 @@ public void setUp() { } @Test - public void testChangeEmail() throws Exception { + void testChangeEmail() throws Exception { changeEmailResponse(changeEmailCode) .expectStatus().isOk() @@ -46,8 +48,8 @@ public void testChangeEmail() throws Exception { .expectBody().jsonPath("$.id").isEqualTo(UNVERIFIED_USER_ID.toString()); User updatedUser = mongoTemplate.findById(UNVERIFIED_USER_ID, User.class).block(); - Assert.assertNull(updatedUser.getNewEmail()); - Assert.assertEquals(NEW_EMAIL, updatedUser.getEmail()); + assertNull(updatedUser.getNewEmail()); + assertEquals(NEW_EMAIL, updatedUser.getEmail()); changeEmailResponse(changeEmailCode) .expectStatus().isUnauthorized(); @@ -57,7 +59,7 @@ public void testChangeEmail() throws Exception { * Providing a wrong changeEmailCode shouldn't work. */ @Test - public void testChangeEmailWrongCode() throws Exception { + void testChangeEmailWrongCode() throws Exception { // Blank token changeEmailResponse("") @@ -98,9 +100,8 @@ public void testChangeEmailWrongCode() throws Exception { public void testChangeEmailObsoleteCode() throws Exception { // credentials updated after the request for email change was made - Thread.sleep(1L); User user = mongoTemplate.findById(UNVERIFIED_USER_ID, User.class).block(); - user.setCredentialsUpdatedMillis(System.currentTimeMillis()); + user.setCredentialsUpdatedMillis(System.currentTimeMillis() + 1); mongoTemplate.save(user).block(); // A new auth token is needed, because old one would be obsolete! @@ -118,7 +119,7 @@ public void testChangeEmailObsoleteCode() throws Exception { * @throws Exception */ @Test - public void testChangeEmailWithoutAnyRequest() throws Exception { + void testChangeEmailWithoutAnyRequest() throws Exception { CLIENT.post().uri(BASE_URI + "/users/{id}/email", USER_ID) .header(HttpHeaders.AUTHORIZATION, TOKENS.get(USER_ID)) diff --git a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/ChangePasswordTests.java b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/ChangePasswordTests.java index 6d0c1cbb..a7c0d04c 100644 --- a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/ChangePasswordTests.java +++ b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/ChangePasswordTests.java @@ -4,7 +4,7 @@ import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; import com.naturalprogrammer.spring.lemondemo.dto.TestErrorResponse; import org.bson.types.ObjectId; -import org.junit.Test; +import org.junit.jupiter.api.Test; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; @@ -13,7 +13,7 @@ import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.*; import static com.naturalprogrammer.spring.lemondemo.controllers.MyController.BASE_URI; -public class ChangePasswordTests extends AbstractTests { +class ChangePasswordTests extends AbstractTests { private static final String NEW_PASSWORD = "a-new-password"; @@ -31,7 +31,7 @@ private ChangePasswordForm changePasswordForm(String oldPassword) { * A non-admin user should be able to change his password. */ @Test - public void testChangePassword() throws Exception { + void testChangePassword() throws Exception { CLIENT.post().uri(BASE_URI + "/users/{id}/password", UNVERIFIED_USER_ID) .header(HttpHeaders.AUTHORIZATION, TOKENS.get(UNVERIFIED_USER_ID)) @@ -50,7 +50,7 @@ public void testChangePassword() throws Exception { * An good admin user should be able to change the password of another user. */ @Test - public void testAdminChangePasswordAnotherUser() throws Exception { + void testAdminChangePasswordAnotherUser() throws Exception { CLIENT.post().uri(BASE_URI + "/users/{id}/password", UNVERIFIED_USER_ID) .header(HttpHeaders.AUTHORIZATION, TOKENS.get(ADMIN_ID)) @@ -68,7 +68,7 @@ public void testAdminChangePasswordAnotherUser() throws Exception { * Providing an unknown id should return 404. */ @Test - public void testChangePasswordUnknownId() throws Exception { + void testChangePasswordUnknownId() throws Exception { CLIENT.post().uri(BASE_URI + "/users/{id}/password", ObjectId.get()) .header(HttpHeaders.AUTHORIZATION, TOKENS.get(ADMIN_ID)) @@ -83,7 +83,7 @@ public void testChangePasswordUnknownId() throws Exception { * A non-admin user should not be able to change others' password. */ @Test - public void testChangePasswordAnotherUser() throws Exception { + void testChangePasswordAnotherUser() throws Exception { CLIENT.post().uri(BASE_URI + "/users/{id}/password", UNVERIFIED_USER_ID) .header(HttpHeaders.AUTHORIZATION, TOKENS.get(USER_ID)) @@ -102,7 +102,7 @@ public void testChangePasswordAnotherUser() throws Exception { * A bad admin user should not be able to change others' password. */ @Test - public void testBadAdminChangePasswordAnotherUser() throws Exception { + void testBadAdminChangePasswordAnotherUser() throws Exception { CLIENT.post().uri(BASE_URI + "/users/{id}/password", UNVERIFIED_USER_ID) .header(HttpHeaders.AUTHORIZATION, TOKENS.get(UNVERIFIED_ADMIN_ID)) @@ -118,7 +118,7 @@ public void testBadAdminChangePasswordAnotherUser() throws Exception { @Test - public void testChangePasswordInvalidData() throws Exception { + void testChangePasswordInvalidData() throws Exception { //@formatter:off CLIENT.post().uri(BASE_URI + "/users/{id}/password", UNVERIFIED_USER_ID) diff --git a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/FetchNewTokenTests.java b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/FetchNewTokenTests.java index 18a6c497..5caa9c93 100644 --- a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/FetchNewTokenTests.java +++ b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/FetchNewTokenTests.java @@ -1,21 +1,20 @@ package com.naturalprogrammer.spring.lemondemo; import com.naturalprogrammer.spring.lemondemo.dto.TestToken; -import org.junit.Test; +import org.junit.jupiter.api.Test; import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; import org.springframework.test.web.reactive.server.EntityExchangeResult; import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.*; import static com.naturalprogrammer.spring.lemondemo.controllers.MyController.BASE_URI; -import static org.junit.Assert.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.springframework.web.reactive.function.BodyInserters.fromFormData; -public class FetchNewTokenTests extends AbstractTests { +class FetchNewTokenTests extends AbstractTests { - @Test - public void testFetchNewToken() throws Exception { + void testFetchNewToken() throws Exception { CLIENT.post().uri(BASE_URI + "/fetch-new-auth-token") .contentType(MediaType.APPLICATION_FORM_URLENCODED) @@ -28,7 +27,7 @@ public void testFetchNewToken() throws Exception { @Test - public void testFetchNewTokenExpiration() throws Exception { + void testFetchNewTokenExpiration() throws Exception { CLIENT.post().uri(BASE_URI + "/fetch-new-auth-token") .contentType(MediaType.APPLICATION_FORM_URLENCODED) @@ -57,7 +56,7 @@ public void testFetchNewTokenExpiration() throws Exception { } @Test - public void testFetchNewTokenByAdminForAnotherUser() throws Exception { + void testFetchNewTokenByAdminForAnotherUser() throws Exception { CLIENT.post().uri(BASE_URI + "/fetch-new-auth-token") .contentType(MediaType.APPLICATION_FORM_URLENCODED) @@ -71,7 +70,7 @@ public void testFetchNewTokenByAdminForAnotherUser() throws Exception { @Test - public void testFetchNewTokenByNonAdminForAnotherUser() throws Exception { + void testFetchNewTokenByNonAdminForAnotherUser() throws Exception { CLIENT.post().uri(BASE_URI + "/fetch-new-auth-token") .contentType(MediaType.APPLICATION_FORM_URLENCODED) diff --git a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/FetchUserTests.java b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/FetchUserTests.java index 8a118e46..5826c4f4 100644 --- a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/FetchUserTests.java +++ b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/FetchUserTests.java @@ -1,7 +1,7 @@ package com.naturalprogrammer.spring.lemondemo; import org.bson.types.ObjectId; -import org.junit.Test; +import org.junit.jupiter.api.Test; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; @@ -10,10 +10,10 @@ import static com.naturalprogrammer.spring.lemondemo.controllers.MyController.BASE_URI; import static org.springframework.web.reactive.function.BodyInserters.fromFormData; -public class FetchUserTests extends AbstractTests { +class FetchUserTests extends AbstractTests { @Test - public void testFetchUserById() throws Exception { + void testFetchUserById() throws Exception { CLIENT.get().uri(BASE_URI + "/users/{id}", ADMIN_ID) .exchange() @@ -27,7 +27,7 @@ public void testFetchUserById() throws Exception { } @Test - public void testFetchUserByIdLoggedIn() throws Exception { + void testFetchUserByIdLoggedIn() throws Exception { // Same user logged in CLIENT.get().uri(BASE_URI + "/users/{id}", ADMIN_ID) @@ -61,7 +61,7 @@ public void testFetchUserByIdLoggedIn() throws Exception { } @Test - public void testFetchNonExistingUserById() throws Exception { + void testFetchNonExistingUserById() throws Exception { CLIENT.get().uri(BASE_URI + "/users/{id}", ObjectId.get()) .exchange() @@ -69,7 +69,7 @@ public void testFetchNonExistingUserById() throws Exception { } @Test - public void testFetchUserByEmail() throws Exception { + void testFetchUserByEmail() throws Exception { CLIENT.post().uri(BASE_URI + "/users/fetch-by-email") .contentType(MediaType.APPLICATION_FORM_URLENCODED) @@ -84,7 +84,7 @@ public void testFetchUserByEmail() throws Exception { } @Test - public void testFetchUserByInvalidEmail() throws Exception { + void testFetchUserByInvalidEmail() throws Exception { // email does not exist CLIENT.post().uri(BASE_URI + "/users/fetch-by-email") diff --git a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/ForgotPasswordTests.java b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/ForgotPasswordTests.java index e642bf2d..b3682d80 100644 --- a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/ForgotPasswordTests.java +++ b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/ForgotPasswordTests.java @@ -1,6 +1,6 @@ package com.naturalprogrammer.spring.lemondemo; -import org.junit.Test; +import org.junit.jupiter.api.Test; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; @@ -12,10 +12,10 @@ import static org.mockito.Mockito.verify; import static org.springframework.web.reactive.function.BodyInserters.fromFormData; -public class ForgotPasswordTests extends AbstractTests { +class ForgotPasswordTests extends AbstractTests { @Test - public void testForgotPassword() { + void testForgotPassword() { CLIENT.post().uri(BASE_URI + "/forgot-password") .contentType(MediaType.APPLICATION_FORM_URLENCODED) @@ -27,7 +27,7 @@ public void testForgotPassword() { } @Test - public void testForgotPasswordInvalidEmail() throws Exception { + void testForgotPasswordInvalidEmail() throws Exception { // Unknown email CLIENT.post().uri(BASE_URI + "/forgot-password") diff --git a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/LoginTests.java b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/LoginTests.java index f3e4a7a7..a6de6ab3 100644 --- a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/LoginTests.java +++ b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/LoginTests.java @@ -3,18 +3,18 @@ import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; import com.naturalprogrammer.spring.lemondemo.domain.User; import com.naturalprogrammer.spring.lemondemo.dto.TestUserDto; -import org.junit.Test; +import org.junit.jupiter.api.Test; import org.springframework.http.HttpHeaders; import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.*; import static com.naturalprogrammer.spring.lemondemo.controllers.MyController.BASE_URI; -import static org.junit.Assert.*; +import static org.junit.jupiter.api.Assertions.*; import static org.springframework.web.reactive.function.BodyInserters.fromFormData; -public class LoginTests extends AbstractTests { +class LoginTests extends AbstractTests { @Test - public void testLogin() { + void testLogin() { testUtils.loginResponse(ADMIN_EMAIL, ADMIN_PASSWORD) .expectStatus().isOk() @@ -39,7 +39,7 @@ public void testLogin() { @Test - public void testLoginTokenExpiry() throws Exception { + void testLoginTokenExpiry() throws Exception { String token = login(ADMIN_EMAIL, ADMIN_PASSWORD, 500L); Thread.sleep(501L); @@ -53,7 +53,7 @@ public void testLoginTokenExpiry() throws Exception { @Test - public void testObsoleteToken() throws Exception { + void testObsoleteToken() throws Exception { User user = mongoTemplate.findById(ADMIN_ID, User.class).block(); user.setCredentialsUpdatedMillis(System.currentTimeMillis()); @@ -68,7 +68,7 @@ public void testObsoleteToken() throws Exception { @Test - public void testLoginWrongPassword() throws Exception { + void testLoginWrongPassword() throws Exception { testUtils.loginResponse(ADMIN_EMAIL, "wrong-password") .expectStatus().isUnauthorized(); @@ -76,7 +76,7 @@ public void testLoginWrongPassword() throws Exception { @Test - public void testLoginBlankPassword() throws Exception { + void testLoginBlankPassword() throws Exception { testUtils.loginResponse(ADMIN_EMAIL, "") .expectStatus().isUnauthorized(); @@ -84,7 +84,7 @@ public void testLoginBlankPassword() throws Exception { @Test - public void testTokenLogin() { + void testTokenLogin() { CLIENT.get().uri(BASE_URI + "/context") .header(HttpHeaders.AUTHORIZATION, TOKENS.get(ADMIN_ID)) @@ -96,7 +96,7 @@ public void testTokenLogin() { @Test - public void testTokenLoginWrongToken() { + void testTokenLoginWrongToken() { CLIENT.get().uri(BASE_URI + "/context") .header(HttpHeaders.AUTHORIZATION, "Bearer a-wrong-token") @@ -106,7 +106,7 @@ public void testTokenLoginWrongToken() { @Test - public void testLogout() throws Exception { + void testLogout() throws Exception { CLIENT.post().uri("/logout") .exchange() diff --git a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/MyTestUtils.java b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/MyTestUtils.java index dcf98f27..26696ead 100644 --- a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/MyTestUtils.java +++ b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/MyTestUtils.java @@ -3,6 +3,7 @@ import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; import com.naturalprogrammer.spring.lemondemo.domain.User; import com.naturalprogrammer.spring.lemondemo.dto.TestUserDto; +import lombok.extern.slf4j.Slf4j; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.bson.types.ObjectId; @@ -25,10 +26,9 @@ import static org.springframework.web.reactive.function.BodyInserters.fromFormData; @Component +@Slf4j public class MyTestUtils { - private static Log log = LogFactory.getLog(MyTestUtils.class); - public static final ObjectId ADMIN_ID = ObjectId.get(); public static final ObjectId UNVERIFIED_ADMIN_ID = ObjectId.get(); public static final ObjectId BLOCKED_ADMIN_ID = ObjectId.get(); @@ -88,17 +88,6 @@ public ResponseSpec contextResponse(String token) { .expectStatus().isOk(); } - // @Override -// public void run(String... args) throws Exception { -// -// TOKENS.put(ADMIN_ID, login(ADMIN_EMAIL, ADMIN_PASSWORD)); -// TOKENS.put(UNVERIFIED_ADMIN_ID, login("unverifiedadmin@example.com", ADMIN_PASSWORD)); -// TOKENS.put(BLOCKED_ADMIN_ID, login("blockedadmin@example.com", ADMIN_PASSWORD)); -// TOKENS.put(USER_ID, login("user@example.com", USER_PASSWORD)); -// TOKENS.put(UNVERIFIED_USER_ID, login(UNVERIFIED_USER_EMAIL, USER_PASSWORD)); -// TOKENS.put(BLOCKED_USER_ID, login("blockeduser@example.com", USER_PASSWORD)); -// } -// public void initDatabase() { mongoTemplate.dropCollection("usr").block(); diff --git a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/RequestEmailChangeTests.java b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/RequestEmailChangeTests.java index ca17e25a..153e355b 100644 --- a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/RequestEmailChangeTests.java +++ b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/RequestEmailChangeTests.java @@ -5,8 +5,7 @@ import com.naturalprogrammer.spring.lemondemo.dto.TestEmailForm; import com.naturalprogrammer.spring.lemondemo.dto.TestErrorResponse; import org.bson.types.ObjectId; -import org.junit.Assert; -import org.junit.Test; +import org.junit.jupiter.api.Test; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; @@ -15,11 +14,13 @@ import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.*; import static com.naturalprogrammer.spring.lemondemo.controllers.MyController.BASE_URI; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; -public class RequestEmailChangeTests extends AbstractTests { +class RequestEmailChangeTests extends AbstractTests { private static final String NEW_EMAIL = "new.email@example.com"; @@ -34,7 +35,7 @@ private TestEmailForm form() { @Test - public void testRequestEmailChange() { + void testRequestEmailChange() { CLIENT.post().uri(BASE_URI + "/users/{id}/email-change-request", UNVERIFIED_USER_ID) .header(HttpHeaders.AUTHORIZATION, TOKENS.get(UNVERIFIED_USER_ID)) @@ -46,8 +47,8 @@ public void testRequestEmailChange() { verify(mailSender).send(any()); User updatedUser = mongoTemplate.findById(UNVERIFIED_USER_ID, User.class).block(); - Assert.assertEquals(NEW_EMAIL, updatedUser.getNewEmail()); - Assert.assertEquals(UNVERIFIED_USER_EMAIL, updatedUser.getEmail()); + assertEquals(NEW_EMAIL, updatedUser.getNewEmail()); + assertEquals(UNVERIFIED_USER_EMAIL, updatedUser.getEmail()); } @@ -55,7 +56,7 @@ public void testRequestEmailChange() { * A good admin should be able to request changing email of another user. */ @Test - public void testGoodAdminRequestEmailChange() throws Exception { + void testGoodAdminRequestEmailChange() throws Exception { CLIENT.post().uri(BASE_URI + "/users/{id}/email-change-request", UNVERIFIED_USER_ID) .header(HttpHeaders.AUTHORIZATION, TOKENS.get(ADMIN_ID)) @@ -65,7 +66,7 @@ public void testGoodAdminRequestEmailChange() throws Exception { .expectStatus().isNoContent(); User updatedUser = mongoTemplate.findById(UNVERIFIED_USER_ID, User.class).block(); - Assert.assertEquals(NEW_EMAIL, updatedUser.getNewEmail()); + assertEquals(NEW_EMAIL, updatedUser.getNewEmail()); } @@ -73,7 +74,7 @@ public void testGoodAdminRequestEmailChange() throws Exception { * A request changing email of unknown user. */ @Test - public void testRequestEmailChangeUnknownUser() throws Exception { + void testRequestEmailChangeUnknownUser() throws Exception { CLIENT.post().uri(BASE_URI + "/users/{id}/email-change-request", ObjectId.get()) .header(HttpHeaders.AUTHORIZATION, TOKENS.get(ADMIN_ID)) @@ -91,7 +92,7 @@ public void testRequestEmailChangeUnknownUser() throws Exception { * the email id of another user */ @Test - public void testNonAdminRequestEmailChangeAnotherUser() throws Exception { + void testNonAdminRequestEmailChangeAnotherUser() throws Exception { CLIENT.post().uri(BASE_URI + "/users/{id}/email-change-request", ADMIN_ID) .header(HttpHeaders.AUTHORIZATION, TOKENS.get(USER_ID)) @@ -110,7 +111,7 @@ public void testNonAdminRequestEmailChangeAnotherUser() throws Exception { * of another user */ @Test - public void testBadAdminRequestEmailChangeAnotherUser() throws Exception { + void testBadAdminRequestEmailChangeAnotherUser() throws Exception { CLIENT.post().uri(BASE_URI + "/users/{id}/email-change-request", ADMIN_ID) .header(HttpHeaders.AUTHORIZATION, TOKENS.get(UNVERIFIED_ADMIN_ID)) @@ -126,11 +127,9 @@ public void testBadAdminRequestEmailChangeAnotherUser() throws Exception { /** * Trying with invalid data. - * @throws Exception - * @throws JsonProcessingException */ @Test - public void testRequestEmailChangeWithInvalidData() { + void testRequestEmailChangeWithInvalidData() { // try with null newEmail and password tryRequestingEmailChangeBodySpec(new TestEmailForm()) @@ -214,6 +213,6 @@ public void testRequestEmailChangeWithInvalidData() { private void assertNotChanged() { User updatedUser = mongoTemplate.findById(UNVERIFIED_USER_ID, User.class).block(); - Assert.assertNull(updatedUser.getNewEmail()); + assertNull(updatedUser.getNewEmail()); } } diff --git a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/ResendVerificationMailTests.java b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/ResendVerificationMailTests.java index 9bff18f5..6c1039e9 100644 --- a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/ResendVerificationMailTests.java +++ b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/ResendVerificationMailTests.java @@ -1,7 +1,7 @@ package com.naturalprogrammer.spring.lemondemo; import org.bson.types.ObjectId; -import org.junit.Test; +import org.junit.jupiter.api.Test; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.test.web.reactive.server.WebTestClient.ResponseSpec; @@ -12,10 +12,10 @@ import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; -public class ResendVerificationMailTests extends AbstractTests { +class ResendVerificationMailTests extends AbstractTests { @Test - public void testResendVerificationMail() { + void testResendVerificationMail() { resendVerificationMail(UNVERIFIED_USER_ID, UNVERIFIED_USER_ID) .expectStatus().isNoContent(); @@ -25,7 +25,7 @@ public void testResendVerificationMail() { @Test - public void testAdminResendVerificationMailOtherUser() { + void testAdminResendVerificationMailOtherUser() { resendVerificationMail(UNVERIFIED_USER_ID, ADMIN_ID) .expectStatus().isNoContent(); @@ -33,7 +33,7 @@ public void testAdminResendVerificationMailOtherUser() { @Test - public void testBadAdminResendVerificationMailOtherUser() { + void testBadAdminResendVerificationMailOtherUser() { resendVerificationMail(UNVERIFIED_USER_ID, UNVERIFIED_ADMIN_ID) .expectStatus().isForbidden(); @@ -46,7 +46,7 @@ public void testBadAdminResendVerificationMailOtherUser() { @Test - public void testResendVerificationMailUnauthenticated() { + void testResendVerificationMailUnauthenticated() { CLIENT.post().uri(BASE_URI + "/users/{id}/resend-verification-mail", UNVERIFIED_USER_ID) .exchange() @@ -57,7 +57,7 @@ public void testResendVerificationMailUnauthenticated() { @Test - public void testResendVerificationMailAlreadyVerified() { + void testResendVerificationMailAlreadyVerified() { resendVerificationMail(USER_ID, USER_ID) .expectStatus().isEqualTo(HttpStatus.UNPROCESSABLE_ENTITY); @@ -67,7 +67,7 @@ public void testResendVerificationMailAlreadyVerified() { @Test - public void testResendVerificationMailOtherUser() { + void testResendVerificationMailOtherUser() { resendVerificationMail(UNVERIFIED_USER_ID, USER_ID) .expectStatus().isForbidden(); @@ -77,7 +77,7 @@ public void testResendVerificationMailOtherUser() { @Test - public void testResendVerificationMailNonExistingUser() { + void testResendVerificationMailNonExistingUser() { resendVerificationMail(ObjectId.get(), ADMIN_ID) .expectStatus().isNotFound(); diff --git a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/ResetPasswordTests.java b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/ResetPasswordTests.java index 12a84bca..9d8276ec 100644 --- a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/ResetPasswordTests.java +++ b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/ResetPasswordTests.java @@ -3,8 +3,8 @@ import com.naturalprogrammer.spring.lemon.commons.security.GreenTokenService; import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; import com.naturalprogrammer.spring.lemondemo.dto.TestResetPasswordForm; -import org.junit.Before; -import org.junit.Test; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; @@ -14,14 +14,14 @@ import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.*; import static com.naturalprogrammer.spring.lemondemo.controllers.MyController.BASE_URI; -public class ResetPasswordTests extends AbstractTests { +class ResetPasswordTests extends AbstractTests { private String forgotPasswordCode; @Autowired private GreenTokenService greenTokenService; - @Before + @BeforeEach public void setUp() { forgotPasswordCode = greenTokenService.createToken( @@ -30,7 +30,7 @@ public void setUp() { } @Test - public void testResetPassword() throws Exception { + void testResetPassword() throws Exception { final String NEW_PASSWORD = "newPassword!"; @@ -48,7 +48,7 @@ public void testResetPassword() throws Exception { } @Test - public void testResetPasswordInvalidData() throws Exception { + void testResetPasswordInvalidData() throws Exception { // Wrong code resetPassword("wrong-code", "abc99!") diff --git a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/SignupTests.java b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/SignupTests.java index 01d624a0..48b319af 100644 --- a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/SignupTests.java +++ b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/SignupTests.java @@ -6,7 +6,7 @@ import com.naturalprogrammer.spring.lemondemo.dto.TestLemonFieldError; import com.naturalprogrammer.spring.lemondemo.dto.TestUser; import com.naturalprogrammer.spring.lemondemo.dto.TestUserDto; -import org.junit.Test; +import org.junit.jupiter.api.Test; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.test.web.reactive.server.WebTestClient.ResponseSpec; @@ -18,17 +18,17 @@ import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.*; import static com.naturalprogrammer.spring.lemondemo.controllers.MyController.BASE_URI; -import static org.junit.Assert.*; +import static org.junit.jupiter.api.Assertions.*; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; import static org.springframework.data.mongodb.core.query.Criteria.where; import static org.springframework.data.mongodb.core.query.Query.query; -public class SignupTests extends AbstractTests { +class SignupTests extends AbstractTests { @Test - public void testSignup() throws Exception { + void testSignup() throws Exception { signup("user.foo@example.com", "user123", "User Foo") .expectStatus().isCreated() @@ -58,7 +58,7 @@ public void testSignup() throws Exception { } @Test - public void testSignupWithInvalidData() throws Exception { + void testSignupWithInvalidData() throws Exception { signup("abc", "user1", null) .expectStatus().isEqualTo(HttpStatus.UNPROCESSABLE_ENTITY) @@ -91,7 +91,7 @@ public void testSignupWithInvalidData() throws Exception { } @Test - public void testSignupDuplicateEmail() throws Exception { + void testSignupDuplicateEmail() throws Exception { signup(ADMIN_EMAIL, "user123", "User Foo") .expectStatus().isEqualTo(HttpStatus.UNPROCESSABLE_ENTITY); diff --git a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/UpdateUserTests.java b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/UpdateUserTests.java index 772ce683..9d498563 100644 --- a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/UpdateUserTests.java +++ b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/UpdateUserTests.java @@ -5,7 +5,7 @@ import com.naturalprogrammer.spring.lemondemo.domain.User; import com.naturalprogrammer.spring.lemondemo.dto.TestUserDto; import org.bson.types.ObjectId; -import org.junit.Test; +import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Value; import org.springframework.core.io.Resource; import org.springframework.http.HttpHeaders; @@ -16,10 +16,10 @@ import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.*; import static com.naturalprogrammer.spring.lemondemo.controllers.MyController.BASE_URI; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; -public class UpdateUserTests extends AbstractTests { +class UpdateUserTests extends AbstractTests { private static final String UPDATED_NAME = "Edited name"; @@ -40,10 +40,9 @@ public class UpdateUserTests extends AbstractTests { * but changes in roles should be skipped. * The name of security principal object should also * change in the process. - * @throws Exception */ @Test - public void testUpdateSelf() throws Exception { + void testUpdateSelf() { updateUser(UNVERIFIED_USER_ID, UNVERIFIED_USER_ID, userPatch) .expectStatus().isOk() @@ -79,10 +78,9 @@ public void testUpdateSelf() throws Exception { * The name of security principal object should NOT change in the process, * and the verification code should get set/unset on addition/deletion of * the UNVERIFIED role. - * @throws Exception */ @Test - public void testGoodAdminCanUpdateOther() throws Exception { + void testGoodAdminCanUpdateOther() { updateUser(UNVERIFIED_USER_ID, ADMIN_ID, userPatch) .expectStatus().isOk() @@ -111,7 +109,7 @@ public void testGoodAdminCanUpdateOther() throws Exception { * Providing an unknown id should return 404. */ @Test - public void testUpdateUnknownId() throws Exception { + void testUpdateUnknownId() { updateUser(ObjectId.get(), ADMIN_ID, userPatch) .expectStatus().isNotFound(); @@ -119,10 +117,9 @@ public void testUpdateUnknownId() throws Exception { /** * A non-admin trying to update the name and roles of another user should throw exception - * @throws Exception */ @Test - public void testUpdateAnotherUser() throws Exception { + void testUpdateAnotherUser() { updateUser(ADMIN_ID, UNVERIFIED_USER_ID, userPatch) .expectStatus().isForbidden(); @@ -130,10 +127,9 @@ public void testUpdateAnotherUser() throws Exception { /** * A bad ADMIN trying to update the name and roles of another user should throw exception - * @throws Exception */ @Test - public void testBadAdminUpdateAnotherUser() throws Exception { + void testBadAdminUpdateAnotherUser() { updateUser(UNVERIFIED_USER_ID, UNVERIFIED_ADMIN_ID, userPatch) .expectStatus().isForbidden(); @@ -144,10 +140,9 @@ public void testBadAdminUpdateAnotherUser() throws Exception { /** * A good ADMIN should not be able to change his own roles - * @throws Exception */ @Test - public void goodAdminCanNotUpdateSelfRoles() throws Exception { + void goodAdminCanNotUpdateSelfRoles() { updateUser(ADMIN_ID, ADMIN_ID, userPatchAdminRole) .expectStatus().isOk() @@ -169,10 +164,9 @@ public void goodAdminCanNotUpdateSelfRoles() throws Exception { /** * Invalid name - * @throws Exception */ @Test - public void testUpdateUserInvalidNewName() throws Exception { + void testUpdateUserInvalidNewName() { // Null name updateUser(UNVERIFIED_USER_ID, ADMIN_ID, userPatchNullName) @@ -190,6 +184,5 @@ private ResponseSpec updateUser(ObjectId userId, ObjectId loggedInId, Resource p .header(HttpHeaders.AUTHORIZATION, TOKENS.get(loggedInId)) .body(BodyInserters.fromResource(patch)) .exchange(); - } } diff --git a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/VerificationTests.java b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/VerificationTests.java index 3f715498..51290c0f 100644 --- a/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/VerificationTests.java +++ b/lemon-demo-reactive/src/test/java/com/naturalprogrammer/spring/lemondemo/VerificationTests.java @@ -4,25 +4,25 @@ import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; import com.naturalprogrammer.spring.lemondemo.dto.TestUserDto; import org.bson.types.ObjectId; -import org.junit.Before; -import org.junit.Test; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.test.web.reactive.server.WebTestClient.ResponseSpec; import static com.naturalprogrammer.spring.lemondemo.MyTestUtils.*; import static com.naturalprogrammer.spring.lemondemo.controllers.MyController.BASE_URI; -import static org.junit.Assert.*; +import static org.junit.jupiter.api.Assertions.*; import static org.springframework.web.reactive.function.BodyInserters.fromFormData; -public class VerificationTests extends AbstractTests { +class VerificationTests extends AbstractTests { private String verificationCode; @Autowired private GreenTokenService greenTokenService; - @Before + @BeforeEach public void setUp() { verificationCode = greenTokenService.createToken(GreenTokenService.VERIFY_AUDIENCE, @@ -31,7 +31,7 @@ public void setUp() { } @Test - public void testEmailVerification() throws Exception { + void testEmailVerification() { emailVerification(UNVERIFIED_USER_ID, verificationCode) .expectStatus().isOk() @@ -40,6 +40,7 @@ public void testEmailVerification() throws Exception { .consumeWith(result -> { TestUserDto userDto = result.getResponseBody(); + assert userDto != null; assertEquals(UNVERIFIED_USER_ID, userDto.getId()); assertEquals(0, userDto.getRoles().size()); @@ -53,14 +54,14 @@ public void testEmailVerification() throws Exception { } @Test - public void testEmailVerificationNonExistingUser() throws Exception { + void testEmailVerificationNonExistingUser() throws Exception { emailVerification(ObjectId.get(), verificationCode) .expectStatus().isNotFound(); } @Test - public void testEmailVerificationWrongToken() throws Exception { + void testEmailVerificationWrongToken() throws Exception { // null token CLIENT.post().uri(BASE_URI + "/users/{id}/verification", UNVERIFIED_USER_ID) diff --git a/pom.xml b/pom.xml index 2cf3b376..629c3307 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.naturalprogrammer spring-lemon - 1.0.0.RC4 + 1.0.0.RC5 pom spring-lemon @@ -44,6 +44,12 @@ org.springframework.boot spring-boot-starter-test test + + + org.junit.vintage + junit-vintage-engine + + diff --git a/spring-lemon-commons-jpa/pom.xml b/spring-lemon-commons-jpa/pom.xml index 91e1dda9..1cdcab31 100644 --- a/spring-lemon-commons-jpa/pom.xml +++ b/spring-lemon-commons-jpa/pom.xml @@ -13,7 +13,7 @@ com.naturalprogrammer spring-lemon - 1.0.0.RC4 + 1.0.0.RC5 diff --git a/spring-lemon-commons-mongo/pom.xml b/spring-lemon-commons-mongo/pom.xml index 34ffa738..c8b2a345 100644 --- a/spring-lemon-commons-mongo/pom.xml +++ b/spring-lemon-commons-mongo/pom.xml @@ -13,7 +13,7 @@ com.naturalprogrammer spring-lemon - 1.0.0.RC4 + 1.0.0.RC5 diff --git a/spring-lemon-commons-reactive/pom.xml b/spring-lemon-commons-reactive/pom.xml index 0e65f3a9..8fd7a01e 100644 --- a/spring-lemon-commons-reactive/pom.xml +++ b/spring-lemon-commons-reactive/pom.xml @@ -13,7 +13,7 @@ com.naturalprogrammer spring-lemon - 1.0.0.RC4 + 1.0.0.RC5 diff --git a/spring-lemon-commons-web/pom.xml b/spring-lemon-commons-web/pom.xml index f7d37066..5e9f64b2 100644 --- a/spring-lemon-commons-web/pom.xml +++ b/spring-lemon-commons-web/pom.xml @@ -13,7 +13,7 @@ com.naturalprogrammer spring-lemon - 1.0.0.RC4 + 1.0.0.RC5 diff --git a/spring-lemon-commons/pom.xml b/spring-lemon-commons/pom.xml index bfcb03c8..e6265495 100644 --- a/spring-lemon-commons/pom.xml +++ b/spring-lemon-commons/pom.xml @@ -14,7 +14,7 @@ com.naturalprogrammer spring-lemon - 1.0.0.RC4 + 1.0.0.RC5 diff --git a/spring-lemon-commons/src/test/java/com/naturalprogrammer/spring/lemon/commons/security/LemonJwtServiceTests.java b/spring-lemon-commons/src/test/java/com/naturalprogrammer/spring/lemon/commons/security/LemonJwtServiceTests.java index b0933413..af6bd44c 100644 --- a/spring-lemon-commons/src/test/java/com/naturalprogrammer/spring/lemon/commons/security/LemonJwtServiceTests.java +++ b/spring-lemon-commons/src/test/java/com/naturalprogrammer/spring/lemon/commons/security/LemonJwtServiceTests.java @@ -5,11 +5,13 @@ import com.nimbusds.jwt.JWTClaimsSet; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import org.junit.Assert; -import org.junit.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; import org.springframework.security.authentication.BadCredentialsException; -public class LemonJwtServiceTests { +import static org.junit.jupiter.api.Assertions.assertEquals; + +class LemonJwtServiceTests { private static final Log log = LogFactory.getLog(LemonJwtServiceTests.class); @@ -17,10 +19,10 @@ public class LemonJwtServiceTests { private static final String SECRET1 = "926D96C90030DD58429D2751AC1BDBBC"; private static final String SECRET2 = "538518AB685B514685DA8055C03DDA63"; - private LemonJweService jweService1; - private LemonJweService jweService2; - private LemonJwsService jwsService1; - private LemonJwsService jwsService2; + private final LemonJweService jweService1; + private final LemonJweService jweService2; + private final LemonJwsService jwsService1; + private final LemonJwsService jwsService2; public LemonJwtServiceTests() throws JOSEException { @@ -32,7 +34,7 @@ public LemonJwtServiceTests() throws JOSEException { } @Test - public void testParseToken() { + void testParseToken() { testParseToken(jweService1); testParseToken(jwsService1); @@ -48,22 +50,25 @@ private void testParseToken(LemonTokenService service) { JWTClaimsSet claims = service.parseToken(token, "auth"); log.info("Parsed token."); - Assert.assertEquals("subject", claims.getSubject()); - Assert.assertEquals("abc@example.com", claims.getClaim("username")); + assertEquals("subject", claims.getSubject()); + assertEquals("abc@example.com", claims.getClaim("username")); } - @Test(expected = BadCredentialsException.class) - public void testParseJweTokenWrongAudience() { - - testParseTokenWrongAudience(jweService1); + @Test + void testParseJweTokenWrongAudience() { + + Assertions.assertThrows(BadCredentialsException.class, () -> { + testParseTokenWrongAudience(jweService1); + }); } - @Test(expected = BadCredentialsException.class) - public void testParseJwsTokenWrongAudience() { - - testParseTokenWrongAudience(jwsService1); + @Test + void testParseJwsTokenWrongAudience() { + + Assertions.assertThrows(BadCredentialsException.class, () -> { + testParseTokenWrongAudience(jwsService1); + }); } - private void testParseTokenWrongAudience(LemonTokenService service) { @@ -71,16 +76,20 @@ private void testParseTokenWrongAudience(LemonTokenService service) { service.parseToken(token, "auth2"); } - @Test(expected = BadCredentialsException.class) - public void testParseJweTokenExpired() throws InterruptedException { - - testParseTokenExpired(jweService1); + @Test + void testParseJweTokenExpired() throws InterruptedException { + + Assertions.assertThrows(BadCredentialsException.class, () -> { + testParseTokenExpired(jweService1); + }); } - @Test(expected = BadCredentialsException.class) - public void testParseJwsTokenExpired() throws InterruptedException { - - testParseTokenExpired(jwsService1); + @Test + void testParseJwsTokenExpired() throws InterruptedException { + + Assertions.assertThrows(BadCredentialsException.class, () -> { + testParseTokenExpired(jwsService1); + }); } private void testParseTokenExpired(LemonTokenService service) throws InterruptedException { @@ -90,16 +99,20 @@ private void testParseTokenExpired(LemonTokenService service) throws Interrupted service.parseToken(token, "auth"); } - @Test(expected = BadCredentialsException.class) - public void testParseJweTokenWrongSecret() { - - testParseTokenWrongSecret(jweService1, jweService2); + @Test + void testParseJweTokenWrongSecret() { + + Assertions.assertThrows(BadCredentialsException.class, () -> { + testParseTokenWrongSecret(jweService1, jweService2); + }); } - @Test(expected = BadCredentialsException.class) - public void testParseJwsTokenWrongSecret() { - - testParseTokenWrongSecret(jwsService1, jwsService2); + @Test + void testParseJwsTokenWrongSecret() { + + Assertions.assertThrows(BadCredentialsException.class, () -> { + testParseTokenWrongSecret(jwsService1, jwsService2); + }); } private void testParseTokenWrongSecret(LemonTokenService service1, LemonTokenService service2) { @@ -108,23 +121,26 @@ private void testParseTokenWrongSecret(LemonTokenService service1, LemonTokenSer service2.parseToken(token, "auth"); } - @Test(expected = BadCredentialsException.class) - public void testParseJweTokenCutoffTime() throws InterruptedException { + @Test + void testParseJweTokenCutoffTime() throws InterruptedException { - testParseTokenCutoffTime(jweService1); + Assertions.assertThrows(BadCredentialsException.class, () -> { + testParseTokenCutoffTime(jweService1); + }); } - @Test(expected = BadCredentialsException.class) - public void testParseJwsTokenCutoffTime() throws InterruptedException { + @Test + void testParseJwsTokenCutoffTime() throws InterruptedException { - testParseTokenCutoffTime(jwsService1); + Assertions.assertThrows(BadCredentialsException.class, () -> { + testParseTokenCutoffTime(jwsService1); + }); } private void testParseTokenCutoffTime(LemonTokenService service) throws InterruptedException { String token = service.createToken("auth", "subject", 5000L); - Thread.sleep(1L); - service.parseToken(token, "auth", System.currentTimeMillis()); + service.parseToken(token, "auth", System.currentTimeMillis() + 1); } } diff --git a/spring-lemon-exceptions/pom.xml b/spring-lemon-exceptions/pom.xml index 9250d34c..6707dee3 100644 --- a/spring-lemon-exceptions/pom.xml +++ b/spring-lemon-exceptions/pom.xml @@ -13,7 +13,7 @@ com.naturalprogrammer spring-lemon - 1.0.0.RC4 + 1.0.0.RC5 diff --git a/spring-lemon-jpa/pom.xml b/spring-lemon-jpa/pom.xml index a7a8388b..991c9617 100644 --- a/spring-lemon-jpa/pom.xml +++ b/spring-lemon-jpa/pom.xml @@ -13,7 +13,7 @@ com.naturalprogrammer spring-lemon - 1.0.0.RC4 + 1.0.0.RC5 diff --git a/spring-lemon-reactive/pom.xml b/spring-lemon-reactive/pom.xml index a9e8eb68..8bec4618 100644 --- a/spring-lemon-reactive/pom.xml +++ b/spring-lemon-reactive/pom.xml @@ -13,7 +13,7 @@ com.naturalprogrammer spring-lemon - 1.0.0.RC4 + 1.0.0.RC5 From ec6d134656c1298a84a8a24315b018038558e028 Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Sun, 19 Jul 2020 18:18:27 +0530 Subject: [PATCH 102/116] UUID added to error response, to be uniquely identifiable on logging solutions, e.g. ELK --- .../spring/lemondemo/SignupMvcTests.java | 16 ++++++++++++---- .../exceptions/LemonErrorAttributes.java | 7 +++---- .../spring/lemon/exceptions/ErrorResponse.java | 6 ++++-- .../spring/lemon/exceptions/LemonFieldError.java | 10 +++------- .../handlers/AbstractExceptionHandler.java | 6 ++++-- 5 files changed, 26 insertions(+), 19 deletions(-) diff --git a/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/SignupMvcTests.java b/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/SignupMvcTests.java index 6dc4f511..7d124129 100644 --- a/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/SignupMvcTests.java +++ b/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/SignupMvcTests.java @@ -3,9 +3,12 @@ import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; import com.naturalprogrammer.spring.lemondemo.entities.User; import org.junit.jupiter.api.Test; +import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.test.context.jdbc.Sql; +import javax.validation.ConstraintViolationException; + import static org.hamcrest.Matchers.*; import static org.junit.jupiter.api.Assertions.assertNotEquals; import static org.mockito.ArgumentMatchers.any; @@ -26,15 +29,20 @@ void testSignupWithInvalidData() throws Exception { .contentType(MediaType.APPLICATION_JSON) .content(LecUtils.toJson(invalidUser))) .andExpect(status().is(422)) - .andExpect(jsonPath("$.errors[*].field").value(hasSize(4))) - .andExpect(jsonPath("$.errors[*].field").value(hasItems( + .andExpect(jsonPath("id").isString()) + .andExpect(jsonPath("exceptionId").value(ConstraintViolationException.class.getSimpleName())) + .andExpect(jsonPath("error").value("Unprocessable Entity")) + .andExpect(jsonPath("message").value("Validation Error")) + .andExpect(jsonPath("status").value(HttpStatus.UNPROCESSABLE_ENTITY.value())) + .andExpect(jsonPath("errors[*].field").value(hasSize(4))) + .andExpect(jsonPath("errors[*].field").value(hasItems( "user.email", "user.password", "user.name"))) - .andExpect(jsonPath("$.errors[*].code").value(hasItems( + .andExpect(jsonPath("errors[*].code").value(hasItems( "{com.naturalprogrammer.spring.invalid.email}", "{blank.name}", "{com.naturalprogrammer.spring.invalid.email.size}", "{com.naturalprogrammer.spring.invalid.password.size}"))) - .andExpect(jsonPath("$.errors[*].message").value(hasItems( + .andExpect(jsonPath("errors[*].message").value(hasItems( "Not a well formed email address", "Name required", "Email must be between 4 and 250 characters", diff --git a/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/exceptions/LemonErrorAttributes.java b/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/exceptions/LemonErrorAttributes.java index 788d58df..8dcf7692 100644 --- a/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/exceptions/LemonErrorAttributes.java +++ b/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/exceptions/LemonErrorAttributes.java @@ -2,6 +2,7 @@ import com.naturalprogrammer.spring.lemon.exceptions.ErrorResponseComposer; import com.naturalprogrammer.spring.lemon.exceptions.util.LexUtils; +import lombok.extern.slf4j.Slf4j; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.boot.web.error.ErrorAttributeOptions; @@ -15,13 +16,11 @@ * DefaultExceptionHandlerControllerAdvice, * e.g. exceptions thrown in filters. */ +@Slf4j public class LemonErrorAttributes extends DefaultErrorAttributes { - private static final Log log = LogFactory.getLog(LemonErrorAttributes.class); - static final String HTTP_STATUS_KEY = "httpStatus"; - - private ErrorResponseComposer errorResponseComposer; + private final ErrorResponseComposer errorResponseComposer; public LemonErrorAttributes(ErrorResponseComposer errorResponseComposer) { diff --git a/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/ErrorResponse.java b/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/ErrorResponse.java index 210eaf14..0d5e2364 100644 --- a/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/ErrorResponse.java +++ b/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/ErrorResponse.java @@ -2,6 +2,7 @@ import lombok.Getter; import lombok.Setter; +import lombok.ToString; import java.util.Collection; @@ -9,9 +10,10 @@ * Error DTO, to be sent as response body * in case of errors */ -@Getter @Setter +@Getter @Setter @ToString public class ErrorResponse { - + + private String id; private String exceptionId; private String error; private String message; diff --git a/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/LemonFieldError.java b/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/LemonFieldError.java index 26262108..491159ff 100644 --- a/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/LemonFieldError.java +++ b/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/LemonFieldError.java @@ -16,26 +16,22 @@ /** * Holds a field or form error - * - * @author Sanjay Patel */ @Getter @AllArgsConstructor @ToString public class LemonFieldError implements Serializable { // Name of the field. Null in case of a form level error. - private String field; + private final String field; // Error code. Typically the I18n message-code. - private String code; + private final String code; // Error message - private String message; + private final String message; /** * Converts a set of ConstraintViolations * to a list of FieldErrors - * - * @param constraintViolations */ public static List getErrors( Set> constraintViolations) { diff --git a/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/handlers/AbstractExceptionHandler.java b/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/handlers/AbstractExceptionHandler.java index a893908a..f9eff019 100644 --- a/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/handlers/AbstractExceptionHandler.java +++ b/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/handlers/AbstractExceptionHandler.java @@ -8,6 +8,7 @@ import org.springframework.http.HttpStatus; import java.util.Collection; +import java.util.UUID; /** * Extend this to code an exception handler @@ -16,7 +17,7 @@ public abstract class AbstractExceptionHandler { protected final Log log = LogFactory.getLog(this.getClass()); - private Class exceptionClass; + private final Class exceptionClass; public AbstractExceptionHandler(Class exceptionClass) { this.exceptionClass = exceptionClass; @@ -45,7 +46,8 @@ protected Collection getErrors(T ex) { public ErrorResponse getErrorResponse(T ex) { ErrorResponse errorResponse = new ErrorResponse(); - + + errorResponse.setId(UUID.randomUUID().toString()); errorResponse.setExceptionId(getExceptionId(ex)); errorResponse.setMessage(getMessage(ex)); From 0dbc8cf9b9bc8ffecbce54b147888ec386d9ae8e Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Sun, 26 Jul 2020 10:05:12 +0530 Subject: [PATCH 103/116] Made Validation errors unit testable --- pom.xml | 2 +- ...onCommonsWebTokenAuthenticationFilter.java | 11 ++---- .../LemonExceptionsAutoConfiguration.java | 12 ++---- .../lemon/exceptions/util/LexUtils.java | 37 +++++++++++++------ 4 files changed, 33 insertions(+), 29 deletions(-) diff --git a/pom.xml b/pom.xml index 629c3307..280d0518 100644 --- a/pom.xml +++ b/pom.xml @@ -15,7 +15,7 @@ org.springframework.boot spring-boot-starter-parent - 2.3.0.RELEASE + 2.3.2.RELEASE diff --git a/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/security/LemonCommonsWebTokenAuthenticationFilter.java b/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/security/LemonCommonsWebTokenAuthenticationFilter.java index d92b3c2f..85ad30ee 100644 --- a/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/security/LemonCommonsWebTokenAuthenticationFilter.java +++ b/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/security/LemonCommonsWebTokenAuthenticationFilter.java @@ -7,6 +7,7 @@ import com.naturalprogrammer.spring.lemon.exceptions.util.LexUtils; import com.nimbusds.jwt.JWTClaimsSet; import lombok.AllArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.http.HttpHeaders; @@ -26,11 +27,10 @@ * Filter for token authentication */ @AllArgsConstructor +@Slf4j public class LemonCommonsWebTokenAuthenticationFilter extends OncePerRequestFilter { - private static final Log log = LogFactory.getLog(LemonCommonsWebTokenAuthenticationFilter.class); - - private BlueTokenService blueTokenService; + private final BlueTokenService blueTokenService; @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) @@ -54,7 +54,7 @@ protected void doFilterInternal(HttpServletRequest request, HttpServletResponse } catch (Exception e) { - log.debug("Token authentication failed - " + e.getMessage()); + log.debug("Token authentication failed - {}", e.getMessage()); response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Authentication Failed: " + e.getMessage()); @@ -83,9 +83,6 @@ protected Authentication createAuthToken(String token) { /** * Default behaviour is to throw error. To be overridden in auth service. - * - * @param username - * @return */ protected UserDto fetchUserDto(JWTClaimsSet claims) { throw new AuthenticationCredentialsNotFoundException( diff --git a/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/LemonExceptionsAutoConfiguration.java b/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/LemonExceptionsAutoConfiguration.java index 346c2ad4..8cb881e3 100644 --- a/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/LemonExceptionsAutoConfiguration.java +++ b/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/LemonExceptionsAutoConfiguration.java @@ -2,6 +2,7 @@ import com.naturalprogrammer.spring.lemon.exceptions.handlers.AbstractExceptionHandler; import com.naturalprogrammer.spring.lemon.exceptions.util.LexUtils; +import lombok.extern.slf4j.Slf4j; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.boot.autoconfigure.AutoConfigureBefore; @@ -18,10 +19,9 @@ @Configuration @AutoConfigureBefore({ValidationAutoConfiguration.class}) @ComponentScan(basePackageClasses=AbstractExceptionHandler.class) +@Slf4j public class LemonExceptionsAutoConfiguration { - private static final Log log = LogFactory.getLog(LemonExceptionsAutoConfiguration.class); - public LemonExceptionsAutoConfiguration() { log.info("Created"); } @@ -48,13 +48,7 @@ ErrorResponseComposer errorResponseComposer(List> public ExceptionIdMaker exceptionIdMaker() { log.info("Configuring ExceptionIdMaker"); - return ex -> { - - if (ex == null) - return null; - - return ex.getClass().getSimpleName(); - }; + return LexUtils.EXCEPTION_ID_MAKER; } diff --git a/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/util/LexUtils.java b/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/util/LexUtils.java index d58517b2..5dfa55cc 100644 --- a/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/util/LexUtils.java +++ b/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/util/LexUtils.java @@ -2,8 +2,7 @@ import com.naturalprogrammer.spring.lemon.exceptions.ExceptionIdMaker; import com.naturalprogrammer.spring.lemon.exceptions.MultiErrorException; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; +import lombok.extern.slf4j.Slf4j; import org.springframework.context.MessageSource; import org.springframework.context.i18n.LocaleContextHolder; import org.springframework.http.HttpStatus; @@ -11,6 +10,8 @@ import javax.annotation.PostConstruct; import javax.validation.ConstraintViolationException; +import javax.validation.Validation; +import javax.validation.Validator; import java.util.function.Supplier; /** @@ -18,14 +19,23 @@ * * @author Sanjay Patel */ +@Slf4j public class LexUtils { - - private static final Log log = LogFactory.getLog(LexUtils.class); private static MessageSource messageSource; private static LocalValidatorFactoryBean validator; private static ExceptionIdMaker exceptionIdMaker; - + + private static final Validator DEFAULT_VALIDATOR = Validation.buildDefaultValidatorFactory().getValidator(); + public static final ExceptionIdMaker EXCEPTION_ID_MAKER = ex -> { + + if (ex == null) + return null; + + return ex.getClass().getSimpleName(); + }; + + public static final MultiErrorException NOT_FOUND_EXCEPTION = new MultiErrorException(); /** @@ -59,8 +69,8 @@ public void postConstruct() { */ public static String getMessage(String messageKey, Object... args) { - if (messageSource == null) - return "ApplicationContext unavailable, probably unit test going on"; + if (messageSource == null) // ApplicationContext unavailable, probably unit test going on + return messageKey; // http://stackoverflow.com/questions/10792551/how-to-obtain-a-current-user-locale-from-spring-without-passing-it-as-a-paramete return messageSource.getMessage(messageKey, args, @@ -105,7 +115,7 @@ public static MultiErrorException validateBean(String beanName, T bean, Clas */ public static void ensureFound(T entity) { - LexUtils.validate(entity != null, + validate(entity != null, "com.naturalprogrammer.spring.notFound") .httpStatus(HttpStatus.NOT_FOUND).go(); } @@ -123,14 +133,16 @@ public static Supplier notFoundSupplier() { public static String getExceptionId(Throwable ex) { Throwable root = getRootException(ex); + + if (exceptionIdMaker == null) // in unit tests + return EXCEPTION_ID_MAKER.make(ex); + return exceptionIdMaker.make(root); } private static Throwable getRootException(Throwable ex) { - if (ex == null) return null; - while(ex.getCause() != null) ex = ex.getCause(); @@ -138,7 +150,8 @@ private static Throwable getRootException(Throwable ex) { } - public static LocalValidatorFactoryBean validator() { - return validator; + public static Validator validator() { + return validator == null ? // e.g. in unit tests + DEFAULT_VALIDATOR : validator; } } From 577ac3941aff6608f156929529c15a9281afc735 Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Sat, 19 Dec 2020 09:55:04 +0530 Subject: [PATCH 104/116] Spring Boot 2.4.1 update --- pom.xml | 2 +- .../LemonCommonsWebAutoConfiguration.java | 4 +++ .../MissingPathVariableExceptionHandler.java | 28 +++++++++++++++++++ spring-lemon-commons/pom.xml | 2 +- spring-lemon-exceptions/pom.xml | 2 +- 5 files changed, 35 insertions(+), 3 deletions(-) create mode 100644 spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/exceptions/handlers/MissingPathVariableExceptionHandler.java diff --git a/pom.xml b/pom.xml index 280d0518..63cb1c66 100644 --- a/pom.xml +++ b/pom.xml @@ -15,7 +15,7 @@ org.springframework.boot spring-boot-starter-parent - 2.3.2.RELEASE + 2.4.1 diff --git a/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/LemonCommonsWebAutoConfiguration.java b/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/LemonCommonsWebAutoConfiguration.java index 6dbd02ca..54ebc268 100644 --- a/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/LemonCommonsWebAutoConfiguration.java +++ b/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/LemonCommonsWebAutoConfiguration.java @@ -3,9 +3,11 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.naturalprogrammer.spring.lemon.commons.LemonCommonsAutoConfiguration; import com.naturalprogrammer.spring.lemon.commons.LemonProperties; +import com.naturalprogrammer.spring.lemon.commons.exceptions.handlers.BadCredentialsExceptionHandler; import com.naturalprogrammer.spring.lemon.commonsweb.exceptions.DefaultExceptionHandlerControllerAdvice; import com.naturalprogrammer.spring.lemon.commonsweb.exceptions.LemonErrorAttributes; import com.naturalprogrammer.spring.lemon.commonsweb.exceptions.LemonErrorController; +import com.naturalprogrammer.spring.lemon.commonsweb.exceptions.handlers.MissingPathVariableExceptionHandler; import com.naturalprogrammer.spring.lemon.commonsweb.security.LemonCorsConfigurationSource; import com.naturalprogrammer.spring.lemon.commonsweb.security.LemonWebAuditorAware; import com.naturalprogrammer.spring.lemon.commonsweb.security.LemonWebSecurityConfig; @@ -26,6 +28,7 @@ import org.springframework.boot.web.servlet.error.ErrorController; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.data.domain.AuditorAware; import org.springframework.data.web.config.EnableSpringDataWebSupport; @@ -39,6 +42,7 @@ @Configuration @EnableSpringDataWebSupport @EnableGlobalMethodSecurity(prePostEnabled = true) +@ComponentScan(basePackageClasses= MissingPathVariableExceptionHandler.class) @AutoConfigureBefore({ WebMvcAutoConfiguration.class, ErrorMvcAutoConfiguration.class, diff --git a/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/exceptions/handlers/MissingPathVariableExceptionHandler.java b/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/exceptions/handlers/MissingPathVariableExceptionHandler.java new file mode 100644 index 00000000..8fac4d79 --- /dev/null +++ b/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/exceptions/handlers/MissingPathVariableExceptionHandler.java @@ -0,0 +1,28 @@ +package com.naturalprogrammer.spring.lemon.commonsweb.exceptions.handlers; + +import com.naturalprogrammer.spring.lemon.exceptions.LemonFieldError; +import com.naturalprogrammer.spring.lemon.exceptions.MultiErrorException; +import com.naturalprogrammer.spring.lemon.exceptions.handlers.AbstractExceptionHandler; +import org.springframework.core.Ordered; +import org.springframework.core.annotation.Order; +import org.springframework.http.HttpStatus; +import org.springframework.stereotype.Component; +import org.springframework.web.bind.MissingPathVariableException; + +import java.util.Collection; + +@Component +@Order(Ordered.LOWEST_PRECEDENCE) +public class MissingPathVariableExceptionHandler extends AbstractExceptionHandler { + + public MissingPathVariableExceptionHandler() { + + super(MissingPathVariableException.class); + log.info("Created"); + } + + @Override + public HttpStatus getStatus(MissingPathVariableException ex) { + return HttpStatus.NOT_FOUND; + } +} diff --git a/spring-lemon-commons/pom.xml b/spring-lemon-commons/pom.xml index e6265495..5f20b666 100644 --- a/spring-lemon-commons/pom.xml +++ b/spring-lemon-commons/pom.xml @@ -53,7 +53,7 @@ com.github.fge json-patch - RELEASE + 1.9 diff --git a/spring-lemon-commons-jpa/pom.xml b/spring-lemon-commons-jpa/pom.xml index 1cdcab31..4b1661c0 100644 --- a/spring-lemon-commons-jpa/pom.xml +++ b/spring-lemon-commons-jpa/pom.xml @@ -13,7 +13,7 @@ com.naturalprogrammer spring-lemon - 1.0.0.RC5 + 1.0.0.RC6 diff --git a/spring-lemon-commons-mongo/pom.xml b/spring-lemon-commons-mongo/pom.xml index c8b2a345..6b0e82e3 100644 --- a/spring-lemon-commons-mongo/pom.xml +++ b/spring-lemon-commons-mongo/pom.xml @@ -13,7 +13,7 @@ com.naturalprogrammer spring-lemon - 1.0.0.RC5 + 1.0.0.RC6 diff --git a/spring-lemon-commons-reactive/pom.xml b/spring-lemon-commons-reactive/pom.xml index 8fd7a01e..9696bd21 100644 --- a/spring-lemon-commons-reactive/pom.xml +++ b/spring-lemon-commons-reactive/pom.xml @@ -13,7 +13,7 @@ com.naturalprogrammer spring-lemon - 1.0.0.RC5 + 1.0.0.RC6 diff --git a/spring-lemon-commons-web/pom.xml b/spring-lemon-commons-web/pom.xml index 5e9f64b2..766693d9 100644 --- a/spring-lemon-commons-web/pom.xml +++ b/spring-lemon-commons-web/pom.xml @@ -13,7 +13,7 @@ com.naturalprogrammer spring-lemon - 1.0.0.RC5 + 1.0.0.RC6 diff --git a/spring-lemon-commons/pom.xml b/spring-lemon-commons/pom.xml index 5f20b666..4d7dca54 100644 --- a/spring-lemon-commons/pom.xml +++ b/spring-lemon-commons/pom.xml @@ -14,7 +14,7 @@ com.naturalprogrammer spring-lemon - 1.0.0.RC5 + 1.0.0.RC6 diff --git a/spring-lemon-exceptions/pom.xml b/spring-lemon-exceptions/pom.xml index 4580889e..17999b9e 100644 --- a/spring-lemon-exceptions/pom.xml +++ b/spring-lemon-exceptions/pom.xml @@ -13,7 +13,7 @@ com.naturalprogrammer spring-lemon - 1.0.0.RC5 + 1.0.0.RC6 diff --git a/spring-lemon-jpa/pom.xml b/spring-lemon-jpa/pom.xml index 991c9617..1d3f35b8 100644 --- a/spring-lemon-jpa/pom.xml +++ b/spring-lemon-jpa/pom.xml @@ -13,7 +13,7 @@ com.naturalprogrammer spring-lemon - 1.0.0.RC5 + 1.0.0.RC6 diff --git a/spring-lemon-reactive/pom.xml b/spring-lemon-reactive/pom.xml index 8bec4618..4cb62053 100644 --- a/spring-lemon-reactive/pom.xml +++ b/spring-lemon-reactive/pom.xml @@ -13,7 +13,7 @@ com.naturalprogrammer spring-lemon - 1.0.0.RC5 + 1.0.0.RC6 From d94a26265fac5a8358fcf523473e46ed1bcac071 Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Sat, 21 Aug 2021 11:53:02 +0530 Subject: [PATCH 106/116] License info added to files --- LICENSE.md | 1 - LICENSE.txt | 13 +++++++++++++ .../spring/lemon/commonsjpa/LecjUtils.java | 16 ++++++++++++++++ .../LemonCommonsJpaAutoConfiguration.java | 16 ++++++++++++++++ .../spring/lemon/commonsjpa/LemonEntity.java | 16 ++++++++++++++++ .../lemon/commonsmongo/AbstractDocument.java | 16 ++++++++++++++++ .../spring/lemon/commonsmongo/LecmUtils.java | 16 ++++++++++++++++ .../LemonCommonsMongoAutoConfiguration.java | 16 ++++++++++++++++ .../LemonCommonsReactiveAutoConfiguration.java | 16 ++++++++++++++++ .../exceptions/LemonReactiveErrorAttributes.java | 16 ++++++++++++++++ .../handlers/VersionExceptionHandler.java | 16 ++++++++++++++++ .../LemonCommonsReactiveSecurityConfig.java | 16 ++++++++++++++++ .../security/LemonCorsConfigurationSource.java | 16 ++++++++++++++++ .../security/LemonReactiveAuditorAware.java | 16 ++++++++++++++++ .../lemon/commonsreactive/util/LecrUtils.java | 16 ++++++++++++++++ .../LemonCommonsWebAutoConfiguration.java | 16 ++++++++++++++++ .../DefaultExceptionHandlerControllerAdvice.java | 16 ++++++++++++++++ .../exceptions/LemonErrorAttributes.java | 16 ++++++++++++++++ .../exceptions/LemonErrorController.java | 16 ++++++++++++++++ .../MissingPathVariableExceptionHandler.java | 16 ++++++++++++++++ ...LemonCommonsWebTokenAuthenticationFilter.java | 16 ++++++++++++++++ .../security/LemonCorsConfigurationSource.java | 16 ++++++++++++++++ .../security/LemonWebAuditorAware.java | 16 ++++++++++++++++ .../security/LemonWebSecurityConfig.java | 16 ++++++++++++++++ .../spring/lemon/commonsweb/util/LecwUtils.java | 16 ++++++++++++++++ .../lemon/commons/AbstractLemonService.java | 16 ++++++++++++++++ .../commons/LemonCommonsAutoConfiguration.java | 16 ++++++++++++++++ .../spring/lemon/commons/LemonProperties.java | 16 ++++++++++++++++ .../commons/domain/AbstractAuditorAware.java | 16 ++++++++++++++++ .../lemon/commons/domain/ChangePasswordForm.java | 16 ++++++++++++++++ .../spring/lemon/commons/domain/IdConverter.java | 16 ++++++++++++++++ .../spring/lemon/commons/domain/LemonUser.java | 16 ++++++++++++++++ .../lemon/commons/domain/ResetPasswordForm.java | 16 ++++++++++++++++ .../handlers/AccessDeniedExceptionHandler.java | 16 ++++++++++++++++ .../handlers/BadCredentialsExceptionHandler.java | 16 ++++++++++++++++ .../handlers/JsonParseExceptionHandler.java | 16 ++++++++++++++++ .../handlers/JsonPatchExceptionHandler.java | 16 ++++++++++++++++ .../handlers/JsonProcessingExceptionHandler.java | 16 ++++++++++++++++ .../UsernameNotFoundExceptionHandler.java | 16 ++++++++++++++++ .../spring/lemon/commons/mail/LemonMailData.java | 16 ++++++++++++++++ .../spring/lemon/commons/mail/MailSender.java | 16 ++++++++++++++++ .../lemon/commons/mail/MockMailSender.java | 16 ++++++++++++++++ .../lemon/commons/mail/SmtpMailSender.java | 16 ++++++++++++++++ .../commons/security/AbstractJwtService.java | 16 ++++++++++++++++ .../lemon/commons/security/BlueTokenService.java | 16 ++++++++++++++++ .../commons/security/GreenTokenService.java | 16 ++++++++++++++++ .../commons/security/LemonGrantedAuthority.java | 16 ++++++++++++++++ .../lemon/commons/security/LemonJweService.java | 16 ++++++++++++++++ .../lemon/commons/security/LemonJwsService.java | 16 ++++++++++++++++ .../security/LemonPermissionEvaluator.java | 16 ++++++++++++++++ .../lemon/commons/security/LemonPrincipal.java | 16 ++++++++++++++++ .../commons/security/LemonTokenService.java | 16 ++++++++++++++++ .../security/PermissionEvaluatorEntity.java | 16 ++++++++++++++++ .../spring/lemon/commons/security/UserDto.java | 16 ++++++++++++++++ .../commons/security/UserEditPermission.java | 16 ++++++++++++++++ .../spring/lemon/commons/util/LecUtils.java | 16 ++++++++++++++++ .../spring/lemon/commons/util/UserUtils.java | 16 ++++++++++++++++ .../spring/lemon/commons/validation/Captcha.java | 16 ++++++++++++++++ .../commons/validation/CaptchaValidator.java | 16 ++++++++++++++++ .../lemon/commons/validation/Password.java | 16 ++++++++++++++++ .../lemon/commons/validation/RetypePassword.java | 16 ++++++++++++++++ .../commons/validation/RetypePasswordForm.java | 16 ++++++++++++++++ .../validation/RetypePasswordValidator.java | 16 ++++++++++++++++ .../commons/security/LemonJwtServiceTests.java | 16 ++++++++++++++++ .../spring/lemon/exceptions/ErrorResponse.java | 16 ++++++++++++++++ .../lemon/exceptions/ErrorResponseComposer.java | 16 ++++++++++++++++ .../lemon/exceptions/ExceptionIdMaker.java | 16 ++++++++++++++++ .../LemonExceptionsAutoConfiguration.java | 16 ++++++++++++++++ .../spring/lemon/exceptions/LemonFieldError.java | 16 ++++++++++++++++ .../lemon/exceptions/MultiErrorException.java | 16 ++++++++++++++++ .../lemon/exceptions/VersionException.java | 16 ++++++++++++++++ .../AbstractBadRequestExceptionHandler.java | 16 ++++++++++++++++ .../handlers/AbstractExceptionHandler.java | 16 ++++++++++++++++ .../AbstractValidationExceptionHandler.java | 16 ++++++++++++++++ .../ConstraintViolationExceptionHandler.java | 16 ++++++++++++++++ .../handlers/MultiErrorExceptionHandler.java | 16 ++++++++++++++++ .../WebExchangeBindExceptionHandler.java | 16 ++++++++++++++++ .../spring/lemon/exceptions/util/LexUtils.java | 16 ++++++++++++++++ .../spring/lemon/LemonAutoConfiguration.java | 16 ++++++++++++++++ .../spring/lemon/LemonController.java | 16 ++++++++++++++++ .../spring/lemon/LemonService.java | 16 ++++++++++++++++ .../spring/lemon/domain/AbstractUser.java | 16 ++++++++++++++++ .../lemon/domain/AbstractUserRepository.java | 16 ++++++++++++++++ ...okieOAuth2AuthorizationRequestRepository.java | 16 ++++++++++++++++ .../LemonAuthenticationSuccessHandler.java | 16 ++++++++++++++++ .../lemon/security/LemonJpaSecurityConfig.java | 16 ++++++++++++++++ .../LemonJpaTokenAuthenticationFilter.java | 16 ++++++++++++++++ .../lemon/security/LemonOAuth2UserService.java | 16 ++++++++++++++++ .../lemon/security/LemonOidcUserService.java | 16 ++++++++++++++++ .../lemon/security/LemonUserDetailsService.java | 16 ++++++++++++++++ .../OAuth2AuthenticationFailureHandler.java | 16 ++++++++++++++++ .../OAuth2AuthenticationSuccessHandler.java | 16 ++++++++++++++++ .../spring/lemon/util/LemonUtils.java | 16 ++++++++++++++++ .../spring/lemon/validation/UniqueEmail.java | 16 ++++++++++++++++ .../lemon/validation/UniqueEmailValidator.java | 16 ++++++++++++++++ .../LemonReactiveAutoConfiguration.java | 16 ++++++++++++++++ .../lemonreactive/LemonReactiveController.java | 16 ++++++++++++++++ .../lemonreactive/LemonReactiveService.java | 16 ++++++++++++++++ .../lemonreactive/domain/AbstractMongoUser.java | 16 ++++++++++++++++ .../domain/AbstractMongoUserRepository.java | 16 ++++++++++++++++ .../spring/lemonreactive/forms/EmailForm.java | 16 ++++++++++++++++ .../security/LemonReactiveSecurityConfig.java | 16 ++++++++++++++++ .../LemonReactiveUserDetailsService.java | 16 ++++++++++++++++ ...ieServerOAuth2AuthorizedClientRepository.java | 16 ++++++++++++++++ ...activeOAuth2AuthenticationSuccessHandler.java | 16 ++++++++++++++++ .../spring/lemonreactive/util/LerUtils.java | 16 ++++++++++++++++ .../lemonreactive/validation/UniqueEmail.java | 16 ++++++++++++++++ .../validation/UniqueEmailValidator.java | 16 ++++++++++++++++ 108 files changed, 1709 insertions(+), 1 deletion(-) delete mode 100644 LICENSE.md create mode 100644 LICENSE.txt diff --git a/LICENSE.md b/LICENSE.md deleted file mode 100644 index 62da4936..00000000 --- a/LICENSE.md +++ /dev/null @@ -1 +0,0 @@ -Apache 2.0 diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 00000000..779dbb71 --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,13 @@ +Copyright 2020-2021 the original author or authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this artifact or file except in compliance with the License. +You may obtain a copy of the License at + + https://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/spring-lemon-commons-jpa/src/main/java/com/naturalprogrammer/spring/lemon/commonsjpa/LecjUtils.java b/spring-lemon-commons-jpa/src/main/java/com/naturalprogrammer/spring/lemon/commonsjpa/LecjUtils.java index 62a4862d..93625c0a 100644 --- a/spring-lemon-commons-jpa/src/main/java/com/naturalprogrammer/spring/lemon/commonsjpa/LecjUtils.java +++ b/spring-lemon-commons-jpa/src/main/java/com/naturalprogrammer/spring/lemon/commonsjpa/LecjUtils.java @@ -1,3 +1,19 @@ +/* + * Copyright 2020-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this artifact or file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.naturalprogrammer.spring.lemon.commonsjpa; import com.naturalprogrammer.spring.lemon.exceptions.VersionException; diff --git a/spring-lemon-commons-jpa/src/main/java/com/naturalprogrammer/spring/lemon/commonsjpa/LemonCommonsJpaAutoConfiguration.java b/spring-lemon-commons-jpa/src/main/java/com/naturalprogrammer/spring/lemon/commonsjpa/LemonCommonsJpaAutoConfiguration.java index b71fb0ed..a055fc66 100644 --- a/spring-lemon-commons-jpa/src/main/java/com/naturalprogrammer/spring/lemon/commonsjpa/LemonCommonsJpaAutoConfiguration.java +++ b/spring-lemon-commons-jpa/src/main/java/com/naturalprogrammer/spring/lemon/commonsjpa/LemonCommonsJpaAutoConfiguration.java @@ -1,3 +1,19 @@ +/* + * Copyright 2020-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this artifact or file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.naturalprogrammer.spring.lemon.commonsjpa; import com.naturalprogrammer.spring.lemon.commonsweb.LemonCommonsWebAutoConfiguration; diff --git a/spring-lemon-commons-jpa/src/main/java/com/naturalprogrammer/spring/lemon/commonsjpa/LemonEntity.java b/spring-lemon-commons-jpa/src/main/java/com/naturalprogrammer/spring/lemon/commonsjpa/LemonEntity.java index 88b69fe8..41e638c3 100644 --- a/spring-lemon-commons-jpa/src/main/java/com/naturalprogrammer/spring/lemon/commonsjpa/LemonEntity.java +++ b/spring-lemon-commons-jpa/src/main/java/com/naturalprogrammer/spring/lemon/commonsjpa/LemonEntity.java @@ -1,3 +1,19 @@ +/* + * Copyright 2020-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this artifact or file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.naturalprogrammer.spring.lemon.commonsjpa; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; diff --git a/spring-lemon-commons-mongo/src/main/java/com/naturalprogrammer/spring/lemon/commonsmongo/AbstractDocument.java b/spring-lemon-commons-mongo/src/main/java/com/naturalprogrammer/spring/lemon/commonsmongo/AbstractDocument.java index aa8f90e6..4b989291 100644 --- a/spring-lemon-commons-mongo/src/main/java/com/naturalprogrammer/spring/lemon/commonsmongo/AbstractDocument.java +++ b/spring-lemon-commons-mongo/src/main/java/com/naturalprogrammer/spring/lemon/commonsmongo/AbstractDocument.java @@ -1,3 +1,19 @@ +/* + * Copyright 2020-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this artifact or file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.naturalprogrammer.spring.lemon.commonsmongo; import com.naturalprogrammer.spring.lemon.commons.security.PermissionEvaluatorEntity; diff --git a/spring-lemon-commons-mongo/src/main/java/com/naturalprogrammer/spring/lemon/commonsmongo/LecmUtils.java b/spring-lemon-commons-mongo/src/main/java/com/naturalprogrammer/spring/lemon/commonsmongo/LecmUtils.java index b473fc78..c0843fd2 100644 --- a/spring-lemon-commons-mongo/src/main/java/com/naturalprogrammer/spring/lemon/commonsmongo/LecmUtils.java +++ b/spring-lemon-commons-mongo/src/main/java/com/naturalprogrammer/spring/lemon/commonsmongo/LecmUtils.java @@ -1,3 +1,19 @@ +/* + * Copyright 2020-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this artifact or file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.naturalprogrammer.spring.lemon.commonsmongo; import com.naturalprogrammer.spring.lemon.exceptions.VersionException; diff --git a/spring-lemon-commons-mongo/src/main/java/com/naturalprogrammer/spring/lemon/commonsmongo/LemonCommonsMongoAutoConfiguration.java b/spring-lemon-commons-mongo/src/main/java/com/naturalprogrammer/spring/lemon/commonsmongo/LemonCommonsMongoAutoConfiguration.java index 2e83307d..2c1e730c 100644 --- a/spring-lemon-commons-mongo/src/main/java/com/naturalprogrammer/spring/lemon/commonsmongo/LemonCommonsMongoAutoConfiguration.java +++ b/spring-lemon-commons-mongo/src/main/java/com/naturalprogrammer/spring/lemon/commonsmongo/LemonCommonsMongoAutoConfiguration.java @@ -1,3 +1,19 @@ +/* + * Copyright 2020-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this artifact or file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.naturalprogrammer.spring.lemon.commonsmongo; import com.naturalprogrammer.spring.lemon.commonsreactive.LemonCommonsReactiveAutoConfiguration; diff --git a/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/LemonCommonsReactiveAutoConfiguration.java b/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/LemonCommonsReactiveAutoConfiguration.java index a8094fc7..ae230245 100644 --- a/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/LemonCommonsReactiveAutoConfiguration.java +++ b/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/LemonCommonsReactiveAutoConfiguration.java @@ -1,3 +1,19 @@ +/* + * Copyright 2020-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this artifact or file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.naturalprogrammer.spring.lemon.commonsreactive; import com.fasterxml.jackson.databind.module.SimpleModule; diff --git a/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/exceptions/LemonReactiveErrorAttributes.java b/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/exceptions/LemonReactiveErrorAttributes.java index ea216a03..ac23cf62 100644 --- a/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/exceptions/LemonReactiveErrorAttributes.java +++ b/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/exceptions/LemonReactiveErrorAttributes.java @@ -1,3 +1,19 @@ +/* + * Copyright 2020-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this artifact or file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.naturalprogrammer.spring.lemon.commonsreactive.exceptions; import com.naturalprogrammer.spring.lemon.exceptions.ErrorResponseComposer; diff --git a/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/exceptions/handlers/VersionExceptionHandler.java b/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/exceptions/handlers/VersionExceptionHandler.java index 837efd71..b596faf2 100644 --- a/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/exceptions/handlers/VersionExceptionHandler.java +++ b/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/exceptions/handlers/VersionExceptionHandler.java @@ -1,3 +1,19 @@ +/* + * Copyright 2020-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this artifact or file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.naturalprogrammer.spring.lemon.commonsreactive.exceptions.handlers; import com.naturalprogrammer.spring.lemon.exceptions.VersionException; diff --git a/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/security/LemonCommonsReactiveSecurityConfig.java b/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/security/LemonCommonsReactiveSecurityConfig.java index b6ce2f95..bd01ab1e 100644 --- a/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/security/LemonCommonsReactiveSecurityConfig.java +++ b/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/security/LemonCommonsReactiveSecurityConfig.java @@ -1,3 +1,19 @@ +/* + * Copyright 2020-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this artifact or file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.naturalprogrammer.spring.lemon.commonsreactive.security; import com.naturalprogrammer.spring.lemon.commons.security.BlueTokenService; diff --git a/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/security/LemonCorsConfigurationSource.java b/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/security/LemonCorsConfigurationSource.java index d4201e48..1cb7fad7 100644 --- a/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/security/LemonCorsConfigurationSource.java +++ b/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/security/LemonCorsConfigurationSource.java @@ -1,3 +1,19 @@ +/* + * Copyright 2020-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this artifact or file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.naturalprogrammer.spring.lemon.commonsreactive.security; import com.naturalprogrammer.spring.lemon.commons.LemonProperties; diff --git a/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/security/LemonReactiveAuditorAware.java b/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/security/LemonReactiveAuditorAware.java index 7284224d..2999eee6 100644 --- a/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/security/LemonReactiveAuditorAware.java +++ b/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/security/LemonReactiveAuditorAware.java @@ -1,3 +1,19 @@ +/* + * Copyright 2020-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this artifact or file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.naturalprogrammer.spring.lemon.commonsreactive.security; import com.naturalprogrammer.spring.lemon.commons.domain.AbstractAuditorAware; diff --git a/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/util/LecrUtils.java b/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/util/LecrUtils.java index 5742af65..79ee6353 100644 --- a/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/util/LecrUtils.java +++ b/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/util/LecrUtils.java @@ -1,3 +1,19 @@ +/* + * Copyright 2020-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this artifact or file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.naturalprogrammer.spring.lemon.commonsreactive.util; import com.github.fge.jsonpatch.JsonPatchException; diff --git a/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/LemonCommonsWebAutoConfiguration.java b/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/LemonCommonsWebAutoConfiguration.java index 54ebc268..7cda9726 100644 --- a/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/LemonCommonsWebAutoConfiguration.java +++ b/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/LemonCommonsWebAutoConfiguration.java @@ -1,3 +1,19 @@ +/* + * Copyright 2020-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this artifact or file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.naturalprogrammer.spring.lemon.commonsweb; import com.fasterxml.jackson.databind.ObjectMapper; diff --git a/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/exceptions/DefaultExceptionHandlerControllerAdvice.java b/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/exceptions/DefaultExceptionHandlerControllerAdvice.java index 89b2c03e..a9aefa20 100644 --- a/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/exceptions/DefaultExceptionHandlerControllerAdvice.java +++ b/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/exceptions/DefaultExceptionHandlerControllerAdvice.java @@ -1,3 +1,19 @@ +/* + * Copyright 2020-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this artifact or file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.naturalprogrammer.spring.lemon.commonsweb.exceptions; import com.naturalprogrammer.spring.lemon.exceptions.ErrorResponse; diff --git a/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/exceptions/LemonErrorAttributes.java b/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/exceptions/LemonErrorAttributes.java index 8dcf7692..4e24abc7 100644 --- a/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/exceptions/LemonErrorAttributes.java +++ b/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/exceptions/LemonErrorAttributes.java @@ -1,3 +1,19 @@ +/* + * Copyright 2020-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this artifact or file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.naturalprogrammer.spring.lemon.commonsweb.exceptions; import com.naturalprogrammer.spring.lemon.exceptions.ErrorResponseComposer; diff --git a/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/exceptions/LemonErrorController.java b/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/exceptions/LemonErrorController.java index 4ccf5ba5..72115c81 100644 --- a/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/exceptions/LemonErrorController.java +++ b/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/exceptions/LemonErrorController.java @@ -1,3 +1,19 @@ +/* + * Copyright 2020-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this artifact or file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.naturalprogrammer.spring.lemon.commonsweb.exceptions; import org.apache.commons.logging.Log; diff --git a/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/exceptions/handlers/MissingPathVariableExceptionHandler.java b/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/exceptions/handlers/MissingPathVariableExceptionHandler.java index 8fac4d79..db8c38f7 100644 --- a/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/exceptions/handlers/MissingPathVariableExceptionHandler.java +++ b/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/exceptions/handlers/MissingPathVariableExceptionHandler.java @@ -1,3 +1,19 @@ +/* + * Copyright 2020-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this artifact or file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.naturalprogrammer.spring.lemon.commonsweb.exceptions.handlers; import com.naturalprogrammer.spring.lemon.exceptions.LemonFieldError; diff --git a/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/security/LemonCommonsWebTokenAuthenticationFilter.java b/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/security/LemonCommonsWebTokenAuthenticationFilter.java index 85ad30ee..36ee2ac2 100644 --- a/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/security/LemonCommonsWebTokenAuthenticationFilter.java +++ b/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/security/LemonCommonsWebTokenAuthenticationFilter.java @@ -1,3 +1,19 @@ +/* + * Copyright 2020-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this artifact or file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.naturalprogrammer.spring.lemon.commonsweb.security; import com.naturalprogrammer.spring.lemon.commons.security.BlueTokenService; diff --git a/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/security/LemonCorsConfigurationSource.java b/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/security/LemonCorsConfigurationSource.java index d98ca834..a8c45ccf 100644 --- a/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/security/LemonCorsConfigurationSource.java +++ b/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/security/LemonCorsConfigurationSource.java @@ -1,3 +1,19 @@ +/* + * Copyright 2020-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this artifact or file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.naturalprogrammer.spring.lemon.commonsweb.security; import com.naturalprogrammer.spring.lemon.commons.LemonProperties; diff --git a/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/security/LemonWebAuditorAware.java b/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/security/LemonWebAuditorAware.java index c06bdfa9..5fd170c2 100644 --- a/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/security/LemonWebAuditorAware.java +++ b/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/security/LemonWebAuditorAware.java @@ -1,3 +1,19 @@ +/* + * Copyright 2020-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this artifact or file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.naturalprogrammer.spring.lemon.commonsweb.security; import com.naturalprogrammer.spring.lemon.commons.domain.AbstractAuditorAware; diff --git a/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/security/LemonWebSecurityConfig.java b/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/security/LemonWebSecurityConfig.java index 1ccce3e2..366db641 100644 --- a/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/security/LemonWebSecurityConfig.java +++ b/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/security/LemonWebSecurityConfig.java @@ -1,3 +1,19 @@ +/* + * Copyright 2020-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this artifact or file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.naturalprogrammer.spring.lemon.commonsweb.security; import com.naturalprogrammer.spring.lemon.commons.security.BlueTokenService; diff --git a/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/util/LecwUtils.java b/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/util/LecwUtils.java index 767178ec..11a60a96 100644 --- a/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/util/LecwUtils.java +++ b/spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/util/LecwUtils.java @@ -1,3 +1,19 @@ +/* + * Copyright 2020-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this artifact or file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.naturalprogrammer.spring.lemon.commonsweb.util; import com.naturalprogrammer.spring.lemon.commons.security.UserDto; diff --git a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/AbstractLemonService.java b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/AbstractLemonService.java index 526864ed..cf9c3f0f 100644 --- a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/AbstractLemonService.java +++ b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/AbstractLemonService.java @@ -1,3 +1,19 @@ +/* + * Copyright 2020-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this artifact or file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.naturalprogrammer.spring.lemon.commons; import com.naturalprogrammer.spring.lemon.commons.LemonProperties.Admin; diff --git a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/LemonCommonsAutoConfiguration.java b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/LemonCommonsAutoConfiguration.java index 75bc2a35..1dedaf9b 100644 --- a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/LemonCommonsAutoConfiguration.java +++ b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/LemonCommonsAutoConfiguration.java @@ -1,3 +1,19 @@ +/* + * Copyright 2020-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this artifact or file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.naturalprogrammer.spring.lemon.commons; import com.fasterxml.jackson.databind.ObjectMapper; diff --git a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/LemonProperties.java b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/LemonProperties.java index b023c67e..57aa1180 100644 --- a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/LemonProperties.java +++ b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/LemonProperties.java @@ -1,3 +1,19 @@ +/* + * Copyright 2020-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this artifact or file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.naturalprogrammer.spring.lemon.commons; import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; diff --git a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/domain/AbstractAuditorAware.java b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/domain/AbstractAuditorAware.java index 871eb612..460cefee 100644 --- a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/domain/AbstractAuditorAware.java +++ b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/domain/AbstractAuditorAware.java @@ -1,3 +1,19 @@ +/* + * Copyright 2020-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this artifact or file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.naturalprogrammer.spring.lemon.commons.domain; import com.naturalprogrammer.spring.lemon.commons.security.UserDto; diff --git a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/domain/ChangePasswordForm.java b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/domain/ChangePasswordForm.java index 169eaa09..1b951f96 100644 --- a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/domain/ChangePasswordForm.java +++ b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/domain/ChangePasswordForm.java @@ -1,3 +1,19 @@ +/* + * Copyright 2020-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this artifact or file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.naturalprogrammer.spring.lemon.commons.domain; import com.naturalprogrammer.spring.lemon.commons.validation.Password; diff --git a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/domain/IdConverter.java b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/domain/IdConverter.java index e6c8ced8..97a35222 100644 --- a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/domain/IdConverter.java +++ b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/domain/IdConverter.java @@ -1,3 +1,19 @@ +/* + * Copyright 2020-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this artifact or file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.naturalprogrammer.spring.lemon.commons.domain; import java.io.Serializable; diff --git a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/domain/LemonUser.java b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/domain/LemonUser.java index b9f7aae9..0831e825 100644 --- a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/domain/LemonUser.java +++ b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/domain/LemonUser.java @@ -1,3 +1,19 @@ +/* + * Copyright 2020-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this artifact or file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.naturalprogrammer.spring.lemon.commons.domain; import java.io.Serializable; diff --git a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/domain/ResetPasswordForm.java b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/domain/ResetPasswordForm.java index 1da2b362..e8b43569 100644 --- a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/domain/ResetPasswordForm.java +++ b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/domain/ResetPasswordForm.java @@ -1,3 +1,19 @@ +/* + * Copyright 2020-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this artifact or file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.naturalprogrammer.spring.lemon.commons.domain; import com.naturalprogrammer.spring.lemon.commons.validation.Password; diff --git a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/exceptions/handlers/AccessDeniedExceptionHandler.java b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/exceptions/handlers/AccessDeniedExceptionHandler.java index 64137ba9..91f69c7e 100644 --- a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/exceptions/handlers/AccessDeniedExceptionHandler.java +++ b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/exceptions/handlers/AccessDeniedExceptionHandler.java @@ -1,3 +1,19 @@ +/* + * Copyright 2020-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this artifact or file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.naturalprogrammer.spring.lemon.commons.exceptions.handlers; import com.naturalprogrammer.spring.lemon.exceptions.handlers.AbstractExceptionHandler; diff --git a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/exceptions/handlers/BadCredentialsExceptionHandler.java b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/exceptions/handlers/BadCredentialsExceptionHandler.java index 554934a7..a1b99403 100644 --- a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/exceptions/handlers/BadCredentialsExceptionHandler.java +++ b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/exceptions/handlers/BadCredentialsExceptionHandler.java @@ -1,3 +1,19 @@ +/* + * Copyright 2020-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this artifact or file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.naturalprogrammer.spring.lemon.commons.exceptions.handlers; import com.naturalprogrammer.spring.lemon.exceptions.handlers.AbstractExceptionHandler; diff --git a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/exceptions/handlers/JsonParseExceptionHandler.java b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/exceptions/handlers/JsonParseExceptionHandler.java index 5ba00886..78f6752f 100644 --- a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/exceptions/handlers/JsonParseExceptionHandler.java +++ b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/exceptions/handlers/JsonParseExceptionHandler.java @@ -1,3 +1,19 @@ +/* + * Copyright 2020-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this artifact or file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.naturalprogrammer.spring.lemon.commons.exceptions.handlers; import com.fasterxml.jackson.core.JsonParseException; diff --git a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/exceptions/handlers/JsonPatchExceptionHandler.java b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/exceptions/handlers/JsonPatchExceptionHandler.java index 4b6f0989..3168e94a 100644 --- a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/exceptions/handlers/JsonPatchExceptionHandler.java +++ b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/exceptions/handlers/JsonPatchExceptionHandler.java @@ -1,3 +1,19 @@ +/* + * Copyright 2020-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this artifact or file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.naturalprogrammer.spring.lemon.commons.exceptions.handlers; import com.github.fge.jsonpatch.JsonPatchException; diff --git a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/exceptions/handlers/JsonProcessingExceptionHandler.java b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/exceptions/handlers/JsonProcessingExceptionHandler.java index 034ae770..888fd96e 100644 --- a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/exceptions/handlers/JsonProcessingExceptionHandler.java +++ b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/exceptions/handlers/JsonProcessingExceptionHandler.java @@ -1,3 +1,19 @@ +/* + * Copyright 2020-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this artifact or file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.naturalprogrammer.spring.lemon.commons.exceptions.handlers; import com.fasterxml.jackson.core.JsonProcessingException; diff --git a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/exceptions/handlers/UsernameNotFoundExceptionHandler.java b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/exceptions/handlers/UsernameNotFoundExceptionHandler.java index 78a70c40..6b56e2d8 100644 --- a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/exceptions/handlers/UsernameNotFoundExceptionHandler.java +++ b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/exceptions/handlers/UsernameNotFoundExceptionHandler.java @@ -1,3 +1,19 @@ +/* + * Copyright 2020-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this artifact or file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.naturalprogrammer.spring.lemon.commons.exceptions.handlers; import com.naturalprogrammer.spring.lemon.exceptions.handlers.AbstractExceptionHandler; diff --git a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/mail/LemonMailData.java b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/mail/LemonMailData.java index eaf51c4c..f8d8cb62 100644 --- a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/mail/LemonMailData.java +++ b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/mail/LemonMailData.java @@ -1,3 +1,19 @@ +/* + * Copyright 2020-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this artifact or file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.naturalprogrammer.spring.lemon.commons.mail; import lombok.Getter; diff --git a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/mail/MailSender.java b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/mail/MailSender.java index 7c8a3828..24f288bf 100644 --- a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/mail/MailSender.java +++ b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/mail/MailSender.java @@ -1,3 +1,19 @@ +/* + * Copyright 2020-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this artifact or file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.naturalprogrammer.spring.lemon.commons.mail; /** diff --git a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/mail/MockMailSender.java b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/mail/MockMailSender.java index 959cc693..9bba134c 100644 --- a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/mail/MockMailSender.java +++ b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/mail/MockMailSender.java @@ -1,3 +1,19 @@ +/* + * Copyright 2020-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this artifact or file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.naturalprogrammer.spring.lemon.commons.mail; import org.apache.commons.logging.Log; diff --git a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/mail/SmtpMailSender.java b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/mail/SmtpMailSender.java index 557b2ffe..f3dc2509 100644 --- a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/mail/SmtpMailSender.java +++ b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/mail/SmtpMailSender.java @@ -1,3 +1,19 @@ +/* + * Copyright 2020-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this artifact or file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.naturalprogrammer.spring.lemon.commons.mail; import org.apache.commons.logging.Log; diff --git a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/AbstractJwtService.java b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/AbstractJwtService.java index 5afe0ee4..447018fd 100644 --- a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/AbstractJwtService.java +++ b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/AbstractJwtService.java @@ -1,3 +1,19 @@ +/* + * Copyright 2020-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this artifact or file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.naturalprogrammer.spring.lemon.commons.security; import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; diff --git a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/BlueTokenService.java b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/BlueTokenService.java index 36734a78..26d25b6f 100644 --- a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/BlueTokenService.java +++ b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/BlueTokenService.java @@ -1,3 +1,19 @@ +/* + * Copyright 2020-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this artifact or file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.naturalprogrammer.spring.lemon.commons.security; public interface BlueTokenService extends LemonTokenService { diff --git a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/GreenTokenService.java b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/GreenTokenService.java index 3d515b3d..fdbeff84 100644 --- a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/GreenTokenService.java +++ b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/GreenTokenService.java @@ -1,3 +1,19 @@ +/* + * Copyright 2020-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this artifact or file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.naturalprogrammer.spring.lemon.commons.security; public interface GreenTokenService extends LemonTokenService { diff --git a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/LemonGrantedAuthority.java b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/LemonGrantedAuthority.java index f5a47fad..93a4becd 100644 --- a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/LemonGrantedAuthority.java +++ b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/LemonGrantedAuthority.java @@ -1,3 +1,19 @@ +/* + * Copyright 2020-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this artifact or file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.naturalprogrammer.spring.lemon.commons.security; import lombok.AllArgsConstructor; diff --git a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/LemonJweService.java b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/LemonJweService.java index bf2a6a86..f0cdebc1 100644 --- a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/LemonJweService.java +++ b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/LemonJweService.java @@ -1,3 +1,19 @@ +/* + * Copyright 2020-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this artifact or file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.naturalprogrammer.spring.lemon.commons.security; import com.nimbusds.jose.*; diff --git a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/LemonJwsService.java b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/LemonJwsService.java index 82ad1957..ae0b7cd1 100644 --- a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/LemonJwsService.java +++ b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/LemonJwsService.java @@ -1,3 +1,19 @@ +/* + * Copyright 2020-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this artifact or file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.naturalprogrammer.spring.lemon.commons.security; import com.nimbusds.jose.*; diff --git a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/LemonPermissionEvaluator.java b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/LemonPermissionEvaluator.java index 9063b9b9..20f2e7f4 100644 --- a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/LemonPermissionEvaluator.java +++ b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/LemonPermissionEvaluator.java @@ -1,3 +1,19 @@ +/* + * Copyright 2020-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this artifact or file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.naturalprogrammer.spring.lemon.commons.security; import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; diff --git a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/LemonPrincipal.java b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/LemonPrincipal.java index e8fa2d3b..ee4c2a8e 100644 --- a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/LemonPrincipal.java +++ b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/LemonPrincipal.java @@ -1,3 +1,19 @@ +/* + * Copyright 2020-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this artifact or file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.naturalprogrammer.spring.lemon.commons.security; import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; diff --git a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/LemonTokenService.java b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/LemonTokenService.java index 14ee600c..fb844de9 100644 --- a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/LemonTokenService.java +++ b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/LemonTokenService.java @@ -1,3 +1,19 @@ +/* + * Copyright 2020-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this artifact or file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.naturalprogrammer.spring.lemon.commons.security; import com.nimbusds.jwt.JWTClaimsSet; diff --git a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/PermissionEvaluatorEntity.java b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/PermissionEvaluatorEntity.java index 8e849e4d..738636f6 100644 --- a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/PermissionEvaluatorEntity.java +++ b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/PermissionEvaluatorEntity.java @@ -1,3 +1,19 @@ +/* + * Copyright 2020-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this artifact or file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.naturalprogrammer.spring.lemon.commons.security; public interface PermissionEvaluatorEntity { diff --git a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/UserDto.java b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/UserDto.java index 65d1cf68..9a44c380 100644 --- a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/UserDto.java +++ b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/UserDto.java @@ -1,3 +1,19 @@ +/* + * Copyright 2020-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this artifact or file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.naturalprogrammer.spring.lemon.commons.security; import com.naturalprogrammer.spring.lemon.commons.util.UserUtils; diff --git a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/UserEditPermission.java b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/UserEditPermission.java index ca0cac71..dccc3711 100644 --- a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/UserEditPermission.java +++ b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/security/UserEditPermission.java @@ -1,3 +1,19 @@ +/* + * Copyright 2020-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this artifact or file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.naturalprogrammer.spring.lemon.commons.security; import org.springframework.security.access.prepost.PreAuthorize; diff --git a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/util/LecUtils.java b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/util/LecUtils.java index e2075267..4a89d6ae 100644 --- a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/util/LecUtils.java +++ b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/util/LecUtils.java @@ -1,3 +1,19 @@ +/* + * Copyright 2020-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this artifact or file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.naturalprogrammer.spring.lemon.commons.util; import com.fasterxml.jackson.core.JsonProcessingException; diff --git a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/util/UserUtils.java b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/util/UserUtils.java index 43e2bd65..dc1a3d46 100644 --- a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/util/UserUtils.java +++ b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/util/UserUtils.java @@ -1,3 +1,19 @@ +/* + * Copyright 2020-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this artifact or file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.naturalprogrammer.spring.lemon.commons.util; import com.naturalprogrammer.spring.lemon.commons.security.UserDto; diff --git a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/validation/Captcha.java b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/validation/Captcha.java index 17e637fa..63c93ed7 100644 --- a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/validation/Captcha.java +++ b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/validation/Captcha.java @@ -1,3 +1,19 @@ +/* + * Copyright 2020-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this artifact or file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.naturalprogrammer.spring.lemon.commons.validation; import javax.validation.Constraint; diff --git a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/validation/CaptchaValidator.java b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/validation/CaptchaValidator.java index dc29deb4..42a60d53 100644 --- a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/validation/CaptchaValidator.java +++ b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/validation/CaptchaValidator.java @@ -1,3 +1,19 @@ +/* + * Copyright 2020-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this artifact or file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.naturalprogrammer.spring.lemon.commons.validation; import com.fasterxml.jackson.annotation.JsonProperty; diff --git a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/validation/Password.java b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/validation/Password.java index bf94c676..b7b16ab5 100644 --- a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/validation/Password.java +++ b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/validation/Password.java @@ -1,3 +1,19 @@ +/* + * Copyright 2020-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this artifact or file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.naturalprogrammer.spring.lemon.commons.validation; import com.naturalprogrammer.spring.lemon.commons.util.UserUtils; diff --git a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/validation/RetypePassword.java b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/validation/RetypePassword.java index 171ab268..1286b65f 100644 --- a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/validation/RetypePassword.java +++ b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/validation/RetypePassword.java @@ -1,3 +1,19 @@ +/* + * Copyright 2020-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this artifact or file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.naturalprogrammer.spring.lemon.commons.validation; import javax.validation.Constraint; diff --git a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/validation/RetypePasswordForm.java b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/validation/RetypePasswordForm.java index 743d34cf..30136150 100644 --- a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/validation/RetypePasswordForm.java +++ b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/validation/RetypePasswordForm.java @@ -1,3 +1,19 @@ +/* + * Copyright 2020-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this artifact or file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.naturalprogrammer.spring.lemon.commons.validation; /** diff --git a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/validation/RetypePasswordValidator.java b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/validation/RetypePasswordValidator.java index 367cbad6..0aeeacb0 100644 --- a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/validation/RetypePasswordValidator.java +++ b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/validation/RetypePasswordValidator.java @@ -1,3 +1,19 @@ +/* + * Copyright 2020-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this artifact or file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.naturalprogrammer.spring.lemon.commons.validation; import org.apache.commons.logging.Log; diff --git a/spring-lemon-commons/src/test/java/com/naturalprogrammer/spring/lemon/commons/security/LemonJwtServiceTests.java b/spring-lemon-commons/src/test/java/com/naturalprogrammer/spring/lemon/commons/security/LemonJwtServiceTests.java index af6bd44c..fcad100e 100644 --- a/spring-lemon-commons/src/test/java/com/naturalprogrammer/spring/lemon/commons/security/LemonJwtServiceTests.java +++ b/spring-lemon-commons/src/test/java/com/naturalprogrammer/spring/lemon/commons/security/LemonJwtServiceTests.java @@ -1,3 +1,19 @@ +/* + * Copyright 2020-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this artifact or file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.naturalprogrammer.spring.lemon.commons.security; import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; diff --git a/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/ErrorResponse.java b/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/ErrorResponse.java index 0d5e2364..5e487c45 100644 --- a/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/ErrorResponse.java +++ b/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/ErrorResponse.java @@ -1,3 +1,19 @@ +/* + * Copyright 2020-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this artifact or file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.naturalprogrammer.spring.lemon.exceptions; import lombok.Getter; diff --git a/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/ErrorResponseComposer.java b/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/ErrorResponseComposer.java index f3946302..bb492ff4 100644 --- a/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/ErrorResponseComposer.java +++ b/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/ErrorResponseComposer.java @@ -1,3 +1,19 @@ +/* + * Copyright 2020-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this artifact or file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.naturalprogrammer.spring.lemon.exceptions; import com.naturalprogrammer.spring.lemon.exceptions.handlers.AbstractExceptionHandler; diff --git a/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/ExceptionIdMaker.java b/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/ExceptionIdMaker.java index 8fbe17ed..6d3eb4e0 100644 --- a/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/ExceptionIdMaker.java +++ b/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/ExceptionIdMaker.java @@ -1,3 +1,19 @@ +/* + * Copyright 2020-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this artifact or file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.naturalprogrammer.spring.lemon.exceptions; @FunctionalInterface diff --git a/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/LemonExceptionsAutoConfiguration.java b/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/LemonExceptionsAutoConfiguration.java index 8cb881e3..eebdb1d6 100644 --- a/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/LemonExceptionsAutoConfiguration.java +++ b/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/LemonExceptionsAutoConfiguration.java @@ -1,3 +1,19 @@ +/* + * Copyright 2020-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this artifact or file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.naturalprogrammer.spring.lemon.exceptions; import com.naturalprogrammer.spring.lemon.exceptions.handlers.AbstractExceptionHandler; diff --git a/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/LemonFieldError.java b/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/LemonFieldError.java index 491159ff..26d61aa9 100644 --- a/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/LemonFieldError.java +++ b/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/LemonFieldError.java @@ -1,3 +1,19 @@ +/* + * Copyright 2020-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this artifact or file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.naturalprogrammer.spring.lemon.exceptions; import lombok.AllArgsConstructor; diff --git a/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/MultiErrorException.java b/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/MultiErrorException.java index e8e60f03..a97acf7e 100644 --- a/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/MultiErrorException.java +++ b/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/MultiErrorException.java @@ -1,3 +1,19 @@ +/* + * Copyright 2020-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this artifact or file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.naturalprogrammer.spring.lemon.exceptions; import com.naturalprogrammer.spring.lemon.exceptions.util.LexUtils; diff --git a/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/VersionException.java b/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/VersionException.java index 3395c15d..02a94800 100644 --- a/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/VersionException.java +++ b/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/VersionException.java @@ -1,3 +1,19 @@ +/* + * Copyright 2020-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this artifact or file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.naturalprogrammer.spring.lemon.exceptions; import com.naturalprogrammer.spring.lemon.exceptions.util.LexUtils; diff --git a/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/handlers/AbstractBadRequestExceptionHandler.java b/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/handlers/AbstractBadRequestExceptionHandler.java index 8ddede77..7bcfc478 100644 --- a/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/handlers/AbstractBadRequestExceptionHandler.java +++ b/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/handlers/AbstractBadRequestExceptionHandler.java @@ -1,3 +1,19 @@ +/* + * Copyright 2020-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this artifact or file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.naturalprogrammer.spring.lemon.exceptions.handlers; import org.springframework.core.Ordered; diff --git a/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/handlers/AbstractExceptionHandler.java b/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/handlers/AbstractExceptionHandler.java index f9eff019..b60df021 100644 --- a/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/handlers/AbstractExceptionHandler.java +++ b/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/handlers/AbstractExceptionHandler.java @@ -1,3 +1,19 @@ +/* + * Copyright 2020-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this artifact or file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.naturalprogrammer.spring.lemon.exceptions.handlers; import com.naturalprogrammer.spring.lemon.exceptions.ErrorResponse; diff --git a/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/handlers/AbstractValidationExceptionHandler.java b/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/handlers/AbstractValidationExceptionHandler.java index 1edd8748..40b5fb82 100644 --- a/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/handlers/AbstractValidationExceptionHandler.java +++ b/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/handlers/AbstractValidationExceptionHandler.java @@ -1,3 +1,19 @@ +/* + * Copyright 2020-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this artifact or file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.naturalprogrammer.spring.lemon.exceptions.handlers; import com.naturalprogrammer.spring.lemon.exceptions.util.LexUtils; diff --git a/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/handlers/ConstraintViolationExceptionHandler.java b/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/handlers/ConstraintViolationExceptionHandler.java index cac25177..966237b0 100644 --- a/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/handlers/ConstraintViolationExceptionHandler.java +++ b/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/handlers/ConstraintViolationExceptionHandler.java @@ -1,3 +1,19 @@ +/* + * Copyright 2020-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this artifact or file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.naturalprogrammer.spring.lemon.exceptions.handlers; import com.naturalprogrammer.spring.lemon.exceptions.LemonFieldError; diff --git a/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/handlers/MultiErrorExceptionHandler.java b/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/handlers/MultiErrorExceptionHandler.java index 3080cc50..49a3bbba 100644 --- a/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/handlers/MultiErrorExceptionHandler.java +++ b/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/handlers/MultiErrorExceptionHandler.java @@ -1,3 +1,19 @@ +/* + * Copyright 2020-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this artifact or file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.naturalprogrammer.spring.lemon.exceptions.handlers; import com.naturalprogrammer.spring.lemon.exceptions.LemonFieldError; diff --git a/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/handlers/WebExchangeBindExceptionHandler.java b/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/handlers/WebExchangeBindExceptionHandler.java index f2b10b81..24e67a47 100644 --- a/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/handlers/WebExchangeBindExceptionHandler.java +++ b/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/handlers/WebExchangeBindExceptionHandler.java @@ -1,3 +1,19 @@ +/* + * Copyright 2020-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this artifact or file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.naturalprogrammer.spring.lemon.exceptions.handlers; import com.naturalprogrammer.spring.lemon.exceptions.LemonFieldError; diff --git a/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/util/LexUtils.java b/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/util/LexUtils.java index 5dfa55cc..11970d18 100644 --- a/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/util/LexUtils.java +++ b/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/util/LexUtils.java @@ -1,3 +1,19 @@ +/* + * Copyright 2020-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this artifact or file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.naturalprogrammer.spring.lemon.exceptions.util; import com.naturalprogrammer.spring.lemon.exceptions.ExceptionIdMaker; diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/LemonAutoConfiguration.java b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/LemonAutoConfiguration.java index a72423ce..11d209fc 100644 --- a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/LemonAutoConfiguration.java +++ b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/LemonAutoConfiguration.java @@ -1,3 +1,19 @@ +/* + * Copyright 2020-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this artifact or file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.naturalprogrammer.spring.lemon; import com.fasterxml.jackson.databind.ObjectMapper; diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/LemonController.java b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/LemonController.java index 3f5576ef..4b3045ef 100644 --- a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/LemonController.java +++ b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/LemonController.java @@ -1,3 +1,19 @@ +/* + * Copyright 2020-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this artifact or file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.naturalprogrammer.spring.lemon; import com.fasterxml.jackson.annotation.JsonView; diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/LemonService.java b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/LemonService.java index 56755c8c..2515f7c6 100644 --- a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/LemonService.java +++ b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/LemonService.java @@ -1,3 +1,19 @@ +/* + * Copyright 2020-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this artifact or file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.naturalprogrammer.spring.lemon; import com.naturalprogrammer.spring.lemon.commons.AbstractLemonService; diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/domain/AbstractUser.java b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/domain/AbstractUser.java index cd2360f8..9fcb94cf 100644 --- a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/domain/AbstractUser.java +++ b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/domain/AbstractUser.java @@ -1,3 +1,19 @@ +/* + * Copyright 2020-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this artifact or file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.naturalprogrammer.spring.lemon.domain; import com.fasterxml.jackson.annotation.JsonIgnore; diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/domain/AbstractUserRepository.java b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/domain/AbstractUserRepository.java index e91bad07..4837b71a 100644 --- a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/domain/AbstractUserRepository.java +++ b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/domain/AbstractUserRepository.java @@ -1,3 +1,19 @@ +/* + * Copyright 2020-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this artifact or file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.naturalprogrammer.spring.lemon.domain; import org.springframework.data.jpa.repository.JpaRepository; diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/HttpCookieOAuth2AuthorizationRequestRepository.java b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/HttpCookieOAuth2AuthorizationRequestRepository.java index 80810666..69a94900 100644 --- a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/HttpCookieOAuth2AuthorizationRequestRepository.java +++ b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/HttpCookieOAuth2AuthorizationRequestRepository.java @@ -1,3 +1,19 @@ +/* + * Copyright 2020-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this artifact or file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.naturalprogrammer.spring.lemon.security; import com.naturalprogrammer.spring.lemon.commons.LemonProperties; diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonAuthenticationSuccessHandler.java b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonAuthenticationSuccessHandler.java index b0368f37..190060c0 100644 --- a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonAuthenticationSuccessHandler.java +++ b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonAuthenticationSuccessHandler.java @@ -1,3 +1,19 @@ +/* + * Copyright 2020-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this artifact or file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.naturalprogrammer.spring.lemon.security; import com.fasterxml.jackson.databind.ObjectMapper; diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonJpaSecurityConfig.java b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonJpaSecurityConfig.java index 60282d5d..84755d70 100644 --- a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonJpaSecurityConfig.java +++ b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonJpaSecurityConfig.java @@ -1,3 +1,19 @@ +/* + * Copyright 2020-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this artifact or file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.naturalprogrammer.spring.lemon.security; import com.naturalprogrammer.spring.lemon.commons.LemonProperties; diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonJpaTokenAuthenticationFilter.java b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonJpaTokenAuthenticationFilter.java index 1815fcae..607f62fe 100644 --- a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonJpaTokenAuthenticationFilter.java +++ b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonJpaTokenAuthenticationFilter.java @@ -1,3 +1,19 @@ +/* + * Copyright 2020-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this artifact or file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.naturalprogrammer.spring.lemon.security; import com.naturalprogrammer.spring.lemon.commons.security.BlueTokenService; diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonOAuth2UserService.java b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonOAuth2UserService.java index d4e6e0d2..cab4ef0e 100644 --- a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonOAuth2UserService.java +++ b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonOAuth2UserService.java @@ -1,3 +1,19 @@ +/* + * Copyright 2020-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this artifact or file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.naturalprogrammer.spring.lemon.security; import com.naturalprogrammer.spring.lemon.LemonService; diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonOidcUserService.java b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonOidcUserService.java index 41edcbc4..f39333f3 100644 --- a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonOidcUserService.java +++ b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonOidcUserService.java @@ -1,3 +1,19 @@ +/* + * Copyright 2020-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this artifact or file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.naturalprogrammer.spring.lemon.security; import com.naturalprogrammer.spring.lemon.commons.security.LemonPrincipal; diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonUserDetailsService.java b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonUserDetailsService.java index a0e8dbce..8a48090a 100644 --- a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonUserDetailsService.java +++ b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/LemonUserDetailsService.java @@ -1,3 +1,19 @@ +/* + * Copyright 2020-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this artifact or file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.naturalprogrammer.spring.lemon.security; import com.naturalprogrammer.spring.lemon.commons.security.LemonPrincipal; diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/OAuth2AuthenticationFailureHandler.java b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/OAuth2AuthenticationFailureHandler.java index 643dff95..0a305581 100644 --- a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/OAuth2AuthenticationFailureHandler.java +++ b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/OAuth2AuthenticationFailureHandler.java @@ -1,3 +1,19 @@ +/* + * Copyright 2020-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this artifact or file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.naturalprogrammer.spring.lemon.security; import com.naturalprogrammer.spring.lemon.commons.util.LecUtils; diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/OAuth2AuthenticationSuccessHandler.java b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/OAuth2AuthenticationSuccessHandler.java index 7401ffab..61538256 100644 --- a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/OAuth2AuthenticationSuccessHandler.java +++ b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/security/OAuth2AuthenticationSuccessHandler.java @@ -1,3 +1,19 @@ +/* + * Copyright 2020-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this artifact or file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.naturalprogrammer.spring.lemon.security; import com.naturalprogrammer.spring.lemon.commons.LemonProperties; diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/util/LemonUtils.java b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/util/LemonUtils.java index 1fed8d6b..ef30321b 100644 --- a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/util/LemonUtils.java +++ b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/util/LemonUtils.java @@ -1,3 +1,19 @@ +/* + * Copyright 2020-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this artifact or file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.naturalprogrammer.spring.lemon.util; import com.naturalprogrammer.spring.lemon.commons.security.LemonPrincipal; diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/validation/UniqueEmail.java b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/validation/UniqueEmail.java index 02b094a4..dc1c6ec8 100644 --- a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/validation/UniqueEmail.java +++ b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/validation/UniqueEmail.java @@ -1,3 +1,19 @@ +/* + * Copyright 2020-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this artifact or file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.naturalprogrammer.spring.lemon.validation; import com.naturalprogrammer.spring.lemon.commons.util.UserUtils; diff --git a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/validation/UniqueEmailValidator.java b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/validation/UniqueEmailValidator.java index 68a7bc78..fbb76450 100644 --- a/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/validation/UniqueEmailValidator.java +++ b/spring-lemon-jpa/src/main/java/com/naturalprogrammer/spring/lemon/validation/UniqueEmailValidator.java @@ -1,3 +1,19 @@ +/* + * Copyright 2020-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this artifact or file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.naturalprogrammer.spring.lemon.validation; import com.naturalprogrammer.spring.lemon.domain.AbstractUserRepository; diff --git a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveAutoConfiguration.java b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveAutoConfiguration.java index f9547296..226162e0 100644 --- a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveAutoConfiguration.java +++ b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveAutoConfiguration.java @@ -1,3 +1,19 @@ +/* + * Copyright 2020-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this artifact or file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.naturalprogrammer.spring.lemonreactive; import com.naturalprogrammer.spring.lemon.commons.LemonProperties; diff --git a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveController.java b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveController.java index 0c5eca16..e577c33d 100644 --- a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveController.java +++ b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveController.java @@ -1,3 +1,19 @@ +/* + * Copyright 2020-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this artifact or file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.naturalprogrammer.spring.lemonreactive; import com.naturalprogrammer.spring.lemon.commons.LemonProperties; diff --git a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveService.java b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveService.java index adedbace..38e19039 100644 --- a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveService.java +++ b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/LemonReactiveService.java @@ -1,3 +1,19 @@ +/* + * Copyright 2020-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this artifact or file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.naturalprogrammer.spring.lemonreactive; import com.naturalprogrammer.spring.lemon.commons.AbstractLemonService; diff --git a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/domain/AbstractMongoUser.java b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/domain/AbstractMongoUser.java index 26f169c9..2623d4e2 100644 --- a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/domain/AbstractMongoUser.java +++ b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/domain/AbstractMongoUser.java @@ -1,3 +1,19 @@ +/* + * Copyright 2020-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this artifact or file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.naturalprogrammer.spring.lemonreactive.domain; import com.fasterxml.jackson.annotation.JsonIgnore; diff --git a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/domain/AbstractMongoUserRepository.java b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/domain/AbstractMongoUserRepository.java index ebefc220..84a69a73 100644 --- a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/domain/AbstractMongoUserRepository.java +++ b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/domain/AbstractMongoUserRepository.java @@ -1,3 +1,19 @@ +/* + * Copyright 2020-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this artifact or file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.naturalprogrammer.spring.lemonreactive.domain; import org.springframework.data.mongodb.repository.ReactiveMongoRepository; diff --git a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/forms/EmailForm.java b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/forms/EmailForm.java index baca57b1..e49b335b 100644 --- a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/forms/EmailForm.java +++ b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/forms/EmailForm.java @@ -1,3 +1,19 @@ +/* + * Copyright 2020-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this artifact or file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.naturalprogrammer.spring.lemonreactive.forms; import com.naturalprogrammer.spring.lemon.commons.validation.Password; diff --git a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/security/LemonReactiveSecurityConfig.java b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/security/LemonReactiveSecurityConfig.java index 371d1a50..c604cf54 100644 --- a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/security/LemonReactiveSecurityConfig.java +++ b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/security/LemonReactiveSecurityConfig.java @@ -1,3 +1,19 @@ +/* + * Copyright 2020-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this artifact or file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.naturalprogrammer.spring.lemonreactive.security; import com.naturalprogrammer.spring.lemon.commons.LemonProperties; diff --git a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/security/LemonReactiveUserDetailsService.java b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/security/LemonReactiveUserDetailsService.java index 3b166f5f..c0fd9a9f 100644 --- a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/security/LemonReactiveUserDetailsService.java +++ b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/security/LemonReactiveUserDetailsService.java @@ -1,3 +1,19 @@ +/* + * Copyright 2020-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this artifact or file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.naturalprogrammer.spring.lemonreactive.security; import com.naturalprogrammer.spring.lemon.commons.security.LemonPrincipal; diff --git a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/security/ReactiveCookieServerOAuth2AuthorizedClientRepository.java b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/security/ReactiveCookieServerOAuth2AuthorizedClientRepository.java index 4f43d91f..ca6b97b0 100644 --- a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/security/ReactiveCookieServerOAuth2AuthorizedClientRepository.java +++ b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/security/ReactiveCookieServerOAuth2AuthorizedClientRepository.java @@ -1,3 +1,19 @@ +/* + * Copyright 2020-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this artifact or file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.naturalprogrammer.spring.lemonreactive.security; import com.naturalprogrammer.spring.lemon.commons.LemonProperties; diff --git a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/security/ReactiveOAuth2AuthenticationSuccessHandler.java b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/security/ReactiveOAuth2AuthenticationSuccessHandler.java index 9007cb24..4609a312 100644 --- a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/security/ReactiveOAuth2AuthenticationSuccessHandler.java +++ b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/security/ReactiveOAuth2AuthenticationSuccessHandler.java @@ -1,3 +1,19 @@ +/* + * Copyright 2020-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this artifact or file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.naturalprogrammer.spring.lemonreactive.security; import com.naturalprogrammer.spring.lemon.commons.LemonProperties; diff --git a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/util/LerUtils.java b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/util/LerUtils.java index 60b4d14c..7ce951e6 100644 --- a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/util/LerUtils.java +++ b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/util/LerUtils.java @@ -1,3 +1,19 @@ +/* + * Copyright 2020-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this artifact or file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.naturalprogrammer.spring.lemonreactive.util; import com.naturalprogrammer.spring.lemon.commons.security.LemonTokenService; diff --git a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/validation/UniqueEmail.java b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/validation/UniqueEmail.java index 16f197ce..b67bf6c1 100644 --- a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/validation/UniqueEmail.java +++ b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/validation/UniqueEmail.java @@ -1,3 +1,19 @@ +/* + * Copyright 2020-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this artifact or file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.naturalprogrammer.spring.lemonreactive.validation; import com.naturalprogrammer.spring.lemon.commons.util.UserUtils; diff --git a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/validation/UniqueEmailValidator.java b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/validation/UniqueEmailValidator.java index d0f2e15d..39ad5def 100644 --- a/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/validation/UniqueEmailValidator.java +++ b/spring-lemon-reactive/src/main/java/com/naturalprogrammer/spring/lemonreactive/validation/UniqueEmailValidator.java @@ -1,3 +1,19 @@ +/* + * Copyright 2020-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this artifact or file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.naturalprogrammer.spring.lemonreactive.validation; import com.naturalprogrammer.spring.lemonreactive.LemonReactiveService; From bac0caf8fea51c18259c360ed4acda356d2e0949 Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Sat, 21 Aug 2021 14:02:09 +0530 Subject: [PATCH 107/116] pom updates for uploading to sonatype maven central --- pom.xml | 119 ++++++++++++++---- spring-lemon-commons-jpa/pom.xml | 27 +++- spring-lemon-commons-mongo/pom.xml | 27 +++- spring-lemon-commons-reactive/pom.xml | 27 +++- .../LemonCommonsReactiveSecurityConfig.java | 3 - spring-lemon-commons-web/pom.xml | 27 +++- spring-lemon-commons/pom.xml | 27 +++- .../lemon/commons/AbstractLemonService.java | 4 - .../spring/lemon/commons/util/LecUtils.java | 16 --- spring-lemon-exceptions/pom.xml | 28 ++++- spring-lemon-jpa/pom.xml | 27 +++- spring-lemon-reactive/pom.xml | 27 +++- 12 files changed, 303 insertions(+), 56 deletions(-) diff --git a/pom.xml b/pom.xml index 42d4dae6..e21cf7ef 100644 --- a/pom.xml +++ b/pom.xml @@ -9,8 +9,33 @@ 1.0.0.RC6 pom - spring-lemon + ${project.groupId}:${project.artifactId} Helper library for Spring Boot Web Applications + https://github.com/naturalprogrammer/spring-lemon + + + + Apache License, Version 2.0 + https://www.apache.org/licenses/LICENSE-2.0.txt + repo + + + + + + Sanjay Patel + skpatel20@gmail.com + naturalprogrammer.com + https://www.naturalprogrammer.com + + + + + scm:git:git://github.com/naturalprogrammer/spring-lemon.git + scm:git:git://github.com/naturalprogrammer/spring-lemon.git + https://github.com/naturalprogrammer/spring-lemon + HEAD + org.springframework.boot @@ -58,32 +83,15 @@ - org.apache.maven.plugins - maven-source-plugin - - - attach-sources - - jar - - - - - - - org.apache.maven.plugins - maven-javadoc-plugin + org.sonatype.plugins + nexus-staging-maven-plugin + 1.6.8 + true - false + ossrh + https://s01.oss.sonatype.org/ + true - - - attach-javadocs - - jar - - - @@ -119,4 +127,65 @@ + + + ossrh + https://s01.oss.sonatype.org/content/repositories/snapshots/ + + + + + + release + + + + + org.apache.maven.plugins + maven-source-plugin + 3.2.1 + + + attach-sources + + jar-no-fork + + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + 3.2.0 + + + attach-javadocs + + jar + + + + + + + org.apache.maven.plugins + maven-gpg-plugin + 1.6 + + + sign-artifacts + verify + + sign + + + + + + + + + + diff --git a/spring-lemon-commons-jpa/pom.xml b/spring-lemon-commons-jpa/pom.xml index 4b1661c0..30b59132 100644 --- a/spring-lemon-commons-jpa/pom.xml +++ b/spring-lemon-commons-jpa/pom.xml @@ -7,8 +7,33 @@ spring-lemon-commons-jpa jar - spring-lemon-commons-jpa + ${project.groupId}:${project.artifactId} Spring Lemon Commons JPA + https://github.com/naturalprogrammer/spring-lemon + + + + Apache License, Version 2.0 + https://www.apache.org/licenses/LICENSE-2.0.txt + repo + + + + + + Sanjay Patel + skpatel20@gmail.com + naturalprogrammer.com + https://www.naturalprogrammer.com + + + + + scm:git:git://github.com/naturalprogrammer/spring-lemon.git + scm:git:git://github.com/naturalprogrammer/spring-lemon.git + https://github.com/naturalprogrammer/spring-lemon + HEAD + com.naturalprogrammer diff --git a/spring-lemon-commons-mongo/pom.xml b/spring-lemon-commons-mongo/pom.xml index 6b0e82e3..3de6acc0 100644 --- a/spring-lemon-commons-mongo/pom.xml +++ b/spring-lemon-commons-mongo/pom.xml @@ -7,8 +7,33 @@ spring-lemon-commons-mongo jar - spring-lemon-commons-mongo + ${project.groupId}:${project.artifactId} Spring Lemon Commons MongoDB + https://github.com/naturalprogrammer/spring-lemon + + + + Apache License, Version 2.0 + https://www.apache.org/licenses/LICENSE-2.0.txt + repo + + + + + + Sanjay Patel + skpatel20@gmail.com + naturalprogrammer.com + https://www.naturalprogrammer.com + + + + + scm:git:git://github.com/naturalprogrammer/spring-lemon.git + scm:git:git://github.com/naturalprogrammer/spring-lemon.git + https://github.com/naturalprogrammer/spring-lemon + HEAD + com.naturalprogrammer diff --git a/spring-lemon-commons-reactive/pom.xml b/spring-lemon-commons-reactive/pom.xml index 9696bd21..b1aa7bdd 100644 --- a/spring-lemon-commons-reactive/pom.xml +++ b/spring-lemon-commons-reactive/pom.xml @@ -7,8 +7,33 @@ spring-lemon-commons-reactive jar - spring-lemon-commons-reactive + ${project.groupId}:${project.artifactId} >Helper reactive commons library for Spring Boot REST APIs + https://github.com/naturalprogrammer/spring-lemon + + + + Apache License, Version 2.0 + https://www.apache.org/licenses/LICENSE-2.0.txt + repo + + + + + + Sanjay Patel + skpatel20@gmail.com + naturalprogrammer.com + https://www.naturalprogrammer.com + + + + + scm:git:git://github.com/naturalprogrammer/spring-lemon.git + scm:git:git://github.com/naturalprogrammer/spring-lemon.git + https://github.com/naturalprogrammer/spring-lemon + HEAD + com.naturalprogrammer diff --git a/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/security/LemonCommonsReactiveSecurityConfig.java b/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/security/LemonCommonsReactiveSecurityConfig.java index bd01ab1e..93783938 100644 --- a/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/security/LemonCommonsReactiveSecurityConfig.java +++ b/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/security/LemonCommonsReactiveSecurityConfig.java @@ -125,9 +125,6 @@ protected ReactiveAuthenticationManager tokenAuthenticationManager() { /** * Default behaviour is to throw error. To be overridden in auth service. - * - * @param username - * @return */ protected Mono fetchUserDto(JWTClaimsSet claims) { return Mono.error(new AuthenticationCredentialsNotFoundException( diff --git a/spring-lemon-commons-web/pom.xml b/spring-lemon-commons-web/pom.xml index 766693d9..d79510bf 100644 --- a/spring-lemon-commons-web/pom.xml +++ b/spring-lemon-commons-web/pom.xml @@ -7,8 +7,33 @@ spring-lemon-commons-web jar - spring-lemon-commons-web + ${project.groupId}:${project.artifactId} >Helper commons web library for Spring Boot REST APIs + https://github.com/naturalprogrammer/spring-lemon + + + + Apache License, Version 2.0 + https://www.apache.org/licenses/LICENSE-2.0.txt + repo + + + + + + Sanjay Patel + skpatel20@gmail.com + naturalprogrammer.com + https://www.naturalprogrammer.com + + + + + scm:git:git://github.com/naturalprogrammer/spring-lemon.git + scm:git:git://github.com/naturalprogrammer/spring-lemon.git + https://github.com/naturalprogrammer/spring-lemon + HEAD + com.naturalprogrammer diff --git a/spring-lemon-commons/pom.xml b/spring-lemon-commons/pom.xml index 4d7dca54..65efcc41 100644 --- a/spring-lemon-commons/pom.xml +++ b/spring-lemon-commons/pom.xml @@ -8,8 +8,33 @@ spring-lemon-commons jar - spring-lemon-commons + ${project.groupId}:${project.artifactId} Helper library for Spring Boot Web Applications + https://github.com/naturalprogrammer/spring-lemon + + + + Apache License, Version 2.0 + https://www.apache.org/licenses/LICENSE-2.0.txt + repo + + + + + + Sanjay Patel + skpatel20@gmail.com + naturalprogrammer.com + https://www.naturalprogrammer.com + + + + + scm:git:git://github.com/naturalprogrammer/spring-lemon.git + scm:git:git://github.com/naturalprogrammer/spring-lemon.git + https://github.com/naturalprogrammer/spring-lemon + HEAD + com.naturalprogrammer diff --git a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/AbstractLemonService.java b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/AbstractLemonService.java index cf9c3f0f..219c8f3d 100644 --- a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/AbstractLemonService.java +++ b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/AbstractLemonService.java @@ -50,8 +50,6 @@ public abstract class AbstractLemonService /** * This method is called after the application is ready. * Needs to be public - otherwise Spring screams. - * - * @param event */ @EventListener public void afterApplicationReady(ApplicationReadyEvent event) { @@ -158,8 +156,6 @@ protected void sendVerificationMail(final U user, String verifyLink) { /** * Mails the forgot password link. - * - * @param user */ public void mailForgotPasswordLink(U user) { diff --git a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/util/LecUtils.java b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/util/LecUtils.java index 4a89d6ae..40fb64ae 100644 --- a/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/util/LecUtils.java +++ b/spring-lemon-commons/src/main/java/com/naturalprogrammer/spring/lemon/commons/util/LecUtils.java @@ -79,9 +79,6 @@ public LecUtils(ApplicationContext applicationContext, /** * Extracts the current-user from authentication object - * - * @param auth - * @return */ public static UserDto currentUser(SecurityContext context) { @@ -91,9 +88,6 @@ public static UserDto currentUser(SecurityContext cont /** * Extracts the current-user from authentication object - * - * @param auth - * @return */ public static UserDto currentUser(Authentication auth) { @@ -109,9 +103,6 @@ public static UserDto currentUser(Authentication auth) /** * Throws AccessDeniedException is not authorized - * - * @param authorized - * @param messageKey */ public static void ensureAuthority(boolean authorized, String messageKey) { @@ -123,8 +114,6 @@ public static void ensureAuthority(boolean authorized, String messageKey) { /** * Constructs a map of the key-value pairs, * passed as parameters - * - * @param keyValPair */ @SuppressWarnings("unchecked") public static Map mapOf(Object... keyValPair) { @@ -144,9 +133,6 @@ public static Map mapOf(Object... keyValPair) { /** * Throws BadCredentialsException if not valid - * - * @param valid - * @param messageKey */ public static void ensureCredentials(boolean valid, String messageKey) { @@ -200,8 +186,6 @@ public static ObjectMapper mapper() { /** * Gets the reference to an application-context bean - * - * @param clazz the type of the bean */ public static T getBean(Class clazz) { return applicationContext.getBean(clazz); diff --git a/spring-lemon-exceptions/pom.xml b/spring-lemon-exceptions/pom.xml index 17999b9e..887899a5 100644 --- a/spring-lemon-exceptions/pom.xml +++ b/spring-lemon-exceptions/pom.xml @@ -7,9 +7,35 @@ spring-lemon-exceptions jar - spring-lemon-exceptions + ${project.groupId}:${project.artifactId} Helper exception handling library for Spring Boot REST APIs + https://github.com/naturalprogrammer/spring-lemon + + + + Apache License, Version 2.0 + https://www.apache.org/licenses/LICENSE-2.0.txt + repo + + + + + + Sanjay Patel + skpatel20@gmail.com + naturalprogrammer.com + https://www.naturalprogrammer.com + + + + + scm:git:git://github.com/naturalprogrammer/spring-lemon.git + scm:git:git://github.com/naturalprogrammer/spring-lemon.git + https://github.com/naturalprogrammer/spring-lemon + HEAD + + com.naturalprogrammer spring-lemon diff --git a/spring-lemon-jpa/pom.xml b/spring-lemon-jpa/pom.xml index 1d3f35b8..7c813af5 100644 --- a/spring-lemon-jpa/pom.xml +++ b/spring-lemon-jpa/pom.xml @@ -7,8 +7,33 @@ spring-lemon-jpa jar - spring-lemon-jpa + ${project.groupId}:${project.artifactId} Helper library for Spring Boot JPA Web Applications + https://github.com/naturalprogrammer/spring-lemon + + + + Apache License, Version 2.0 + https://www.apache.org/licenses/LICENSE-2.0.txt + repo + + + + + + Sanjay Patel + skpatel20@gmail.com + naturalprogrammer.com + https://www.naturalprogrammer.com + + + + + scm:git:git://github.com/naturalprogrammer/spring-lemon.git + scm:git:git://github.com/naturalprogrammer/spring-lemon.git + https://github.com/naturalprogrammer/spring-lemon + HEAD + com.naturalprogrammer diff --git a/spring-lemon-reactive/pom.xml b/spring-lemon-reactive/pom.xml index 4cb62053..06763f87 100644 --- a/spring-lemon-reactive/pom.xml +++ b/spring-lemon-reactive/pom.xml @@ -7,8 +7,33 @@ spring-lemon-reactive jar - spring-lemon-reactive + ${project.groupId}:${project.artifactId} Helper reactive library for Spring Boot REST APIs + https://github.com/naturalprogrammer/spring-lemon + + + + Apache License, Version 2.0 + https://www.apache.org/licenses/LICENSE-2.0.txt + repo + + + + + + Sanjay Patel + skpatel20@gmail.com + naturalprogrammer.com + https://www.naturalprogrammer.com + + + + + scm:git:git://github.com/naturalprogrammer/spring-lemon.git + scm:git:git://github.com/naturalprogrammer/spring-lemon.git + https://github.com/naturalprogrammer/spring-lemon + HEAD + com.naturalprogrammer From 0db185da04f19bcaf29808095025b10391d88886 Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Sat, 21 Aug 2021 15:29:38 +0530 Subject: [PATCH 108/116] Getting ready for 1.0.0.RC7 --- lemon-demo-jpa/pom.xml | 2 +- lemon-demo-reactive/pom.xml | 2 +- pom.xml | 2 +- spring-lemon-commons-jpa/pom.xml | 2 +- spring-lemon-commons-mongo/pom.xml | 2 +- spring-lemon-commons-reactive/pom.xml | 2 +- spring-lemon-commons-web/pom.xml | 2 +- spring-lemon-commons/pom.xml | 2 +- spring-lemon-exceptions/pom.xml | 2 +- spring-lemon-jpa/pom.xml | 2 +- spring-lemon-reactive/pom.xml | 2 +- 11 files changed, 11 insertions(+), 11 deletions(-) diff --git a/lemon-demo-jpa/pom.xml b/lemon-demo-jpa/pom.xml index 000604a4..7d1f9f43 100644 --- a/lemon-demo-jpa/pom.xml +++ b/lemon-demo-jpa/pom.xml @@ -14,7 +14,7 @@ com.naturalprogrammer spring-lemon - 1.0.0.RC6 + 1.0.0.RC7 diff --git a/lemon-demo-reactive/pom.xml b/lemon-demo-reactive/pom.xml index a91bd925..d1d6596c 100644 --- a/lemon-demo-reactive/pom.xml +++ b/lemon-demo-reactive/pom.xml @@ -13,7 +13,7 @@ com.naturalprogrammer spring-lemon - 1.0.0.RC6 + 1.0.0.RC7 diff --git a/pom.xml b/pom.xml index e21cf7ef..b7c077a7 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.naturalprogrammer spring-lemon - 1.0.0.RC6 + 1.0.0.RC7 pom ${project.groupId}:${project.artifactId} diff --git a/spring-lemon-commons-jpa/pom.xml b/spring-lemon-commons-jpa/pom.xml index 30b59132..a7f9024d 100644 --- a/spring-lemon-commons-jpa/pom.xml +++ b/spring-lemon-commons-jpa/pom.xml @@ -38,7 +38,7 @@ com.naturalprogrammer spring-lemon - 1.0.0.RC6 + 1.0.0.RC7 diff --git a/spring-lemon-commons-mongo/pom.xml b/spring-lemon-commons-mongo/pom.xml index 3de6acc0..3ddca92c 100644 --- a/spring-lemon-commons-mongo/pom.xml +++ b/spring-lemon-commons-mongo/pom.xml @@ -38,7 +38,7 @@ com.naturalprogrammer spring-lemon - 1.0.0.RC6 + 1.0.0.RC7 diff --git a/spring-lemon-commons-reactive/pom.xml b/spring-lemon-commons-reactive/pom.xml index b1aa7bdd..cfb2a12b 100644 --- a/spring-lemon-commons-reactive/pom.xml +++ b/spring-lemon-commons-reactive/pom.xml @@ -38,7 +38,7 @@ com.naturalprogrammer spring-lemon - 1.0.0.RC6 + 1.0.0.RC7 diff --git a/spring-lemon-commons-web/pom.xml b/spring-lemon-commons-web/pom.xml index d79510bf..2857363c 100644 --- a/spring-lemon-commons-web/pom.xml +++ b/spring-lemon-commons-web/pom.xml @@ -38,7 +38,7 @@ com.naturalprogrammer spring-lemon - 1.0.0.RC6 + 1.0.0.RC7 diff --git a/spring-lemon-commons/pom.xml b/spring-lemon-commons/pom.xml index 65efcc41..e88a105c 100644 --- a/spring-lemon-commons/pom.xml +++ b/spring-lemon-commons/pom.xml @@ -39,7 +39,7 @@ com.naturalprogrammer spring-lemon - 1.0.0.RC6 + 1.0.0.RC7 diff --git a/spring-lemon-exceptions/pom.xml b/spring-lemon-exceptions/pom.xml index 887899a5..15778c8a 100644 --- a/spring-lemon-exceptions/pom.xml +++ b/spring-lemon-exceptions/pom.xml @@ -39,7 +39,7 @@ com.naturalprogrammer spring-lemon - 1.0.0.RC6 + 1.0.0.RC7 diff --git a/spring-lemon-jpa/pom.xml b/spring-lemon-jpa/pom.xml index 7c813af5..8f037824 100644 --- a/spring-lemon-jpa/pom.xml +++ b/spring-lemon-jpa/pom.xml @@ -38,7 +38,7 @@ com.naturalprogrammer spring-lemon - 1.0.0.RC6 + 1.0.0.RC7 diff --git a/spring-lemon-reactive/pom.xml b/spring-lemon-reactive/pom.xml index 06763f87..39c75726 100644 --- a/spring-lemon-reactive/pom.xml +++ b/spring-lemon-reactive/pom.xml @@ -38,7 +38,7 @@ com.naturalprogrammer spring-lemon - 1.0.0.RC6 + 1.0.0.RC7 From 2307248acb5180b95f68c69bba43727db3f703fa Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Sat, 21 Aug 2021 15:30:44 +0530 Subject: [PATCH 109/116] #41: Null pointer fix in LexUtils.getRootException(Throwable ex) --- .../spring/lemon/exceptions/util/LexUtils.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/util/LexUtils.java b/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/util/LexUtils.java index 11970d18..2b6dbbe1 100644 --- a/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/util/LexUtils.java +++ b/spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/util/LexUtils.java @@ -158,7 +158,10 @@ public static String getExceptionId(Throwable ex) { private static Throwable getRootException(Throwable ex) { - + + if (ex == null) + return null; + while(ex.getCause() != null) ex = ex.getCause(); From 582967d12b070fc7b51cfc4e962acfda0ba37611 Mon Sep 17 00:00:00 2001 From: Ilyas Sarsenbaev Date: Tue, 31 Aug 2021 18:05:32 +0500 Subject: [PATCH 110/116] Added jacaco plugin --- lemon-demo-jpa/pom.xml | 21 +++++++++++++++++++++ pom.xml | 1 + 2 files changed, 22 insertions(+) diff --git a/lemon-demo-jpa/pom.xml b/lemon-demo-jpa/pom.xml index 7d1f9f43..4e05155b 100644 --- a/lemon-demo-jpa/pom.xml +++ b/lemon-demo-jpa/pom.xml @@ -50,6 +50,27 @@ org.springframework.boot spring-boot-maven-plugin + + + org.jacoco + jacoco-maven-plugin + ${jacacoVersion} + + + + prepare-agent + + + + report + test + + report + + + + + diff --git a/pom.xml b/pom.xml index b7c077a7..5636fffc 100644 --- a/pom.xml +++ b/pom.xml @@ -101,6 +101,7 @@ UTF-8 UTF-8 1.8 + 0.8.7 From aa0e992cd330e06dd7fc384f52f8301b64a07560 Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Sat, 20 Nov 2021 14:09:58 +0530 Subject: [PATCH 111/116] Release 1.0.1 (For Spring Boot 2.6.0) --- lemon-demo-jpa/pom.xml | 2 +- .../spring/lemondemo/AbstractMvcTests.java | 2 +- lemon-demo-reactive/pom.xml | 2 +- pom.xml | 4 +- spring-lemon-commons-jpa/pom.xml | 2 +- spring-lemon-commons-mongo/pom.xml | 2 +- spring-lemon-commons-reactive/pom.xml | 2 +- ...ficientAuthenticationExceptionHandler.java | 39 +++++++++++++++++++ spring-lemon-commons-web/pom.xml | 2 +- spring-lemon-commons/pom.xml | 2 +- spring-lemon-exceptions/pom.xml | 2 +- spring-lemon-jpa/pom.xml | 2 +- spring-lemon-reactive/pom.xml | 2 +- 13 files changed, 52 insertions(+), 13 deletions(-) create mode 100644 spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/exceptions/handlers/InsufficientAuthenticationExceptionHandler.java diff --git a/lemon-demo-jpa/pom.xml b/lemon-demo-jpa/pom.xml index 4e05155b..945adccd 100644 --- a/lemon-demo-jpa/pom.xml +++ b/lemon-demo-jpa/pom.xml @@ -14,7 +14,7 @@ com.naturalprogrammer spring-lemon - 1.0.0.RC7 + 1.0.1 diff --git a/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/AbstractMvcTests.java b/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/AbstractMvcTests.java index 8660282d..a49345e3 100644 --- a/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/AbstractMvcTests.java +++ b/lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/AbstractMvcTests.java @@ -30,7 +30,7 @@ "lemon.recaptcha.sitekey=" }) @AutoConfigureMockMvc -@AutoConfigureTestDatabase(connection = EmbeddedDatabaseConnection.HSQL) +@AutoConfigureTestDatabase(connection = EmbeddedDatabaseConnection.HSQLDB) @Sql({"/test-data/initialize.sql", "/test-data/finalize.sql"}) public abstract class AbstractMvcTests { diff --git a/lemon-demo-reactive/pom.xml b/lemon-demo-reactive/pom.xml index d1d6596c..197b903a 100644 --- a/lemon-demo-reactive/pom.xml +++ b/lemon-demo-reactive/pom.xml @@ -13,7 +13,7 @@ com.naturalprogrammer spring-lemon - 1.0.0.RC7 + 1.0.1 diff --git a/pom.xml b/pom.xml index 5636fffc..b41ef488 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.naturalprogrammer spring-lemon - 1.0.0.RC7 + 1.0.1 pom ${project.groupId}:${project.artifactId} @@ -40,7 +40,7 @@ org.springframework.boot spring-boot-starter-parent - 2.5.2 + 2.6.0 diff --git a/spring-lemon-commons-jpa/pom.xml b/spring-lemon-commons-jpa/pom.xml index a7f9024d..6a4f7a55 100644 --- a/spring-lemon-commons-jpa/pom.xml +++ b/spring-lemon-commons-jpa/pom.xml @@ -38,7 +38,7 @@ com.naturalprogrammer spring-lemon - 1.0.0.RC7 + 1.0.1 diff --git a/spring-lemon-commons-mongo/pom.xml b/spring-lemon-commons-mongo/pom.xml index 3ddca92c..a18dbbec 100644 --- a/spring-lemon-commons-mongo/pom.xml +++ b/spring-lemon-commons-mongo/pom.xml @@ -38,7 +38,7 @@ com.naturalprogrammer spring-lemon - 1.0.0.RC7 + 1.0.1 diff --git a/spring-lemon-commons-reactive/pom.xml b/spring-lemon-commons-reactive/pom.xml index cfb2a12b..dc841ffb 100644 --- a/spring-lemon-commons-reactive/pom.xml +++ b/spring-lemon-commons-reactive/pom.xml @@ -38,7 +38,7 @@ com.naturalprogrammer spring-lemon - 1.0.0.RC7 + 1.0.1 diff --git a/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/exceptions/handlers/InsufficientAuthenticationExceptionHandler.java b/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/exceptions/handlers/InsufficientAuthenticationExceptionHandler.java new file mode 100644 index 00000000..4e98c085 --- /dev/null +++ b/spring-lemon-commons-reactive/src/main/java/com/naturalprogrammer/spring/lemon/commonsreactive/exceptions/handlers/InsufficientAuthenticationExceptionHandler.java @@ -0,0 +1,39 @@ +/* + * Copyright 2020-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this artifact or file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.naturalprogrammer.spring.lemon.commonsreactive.exceptions.handlers; + +import com.naturalprogrammer.spring.lemon.exceptions.handlers.AbstractExceptionHandler; +import org.springframework.core.Ordered; +import org.springframework.core.annotation.Order; +import org.springframework.http.HttpStatus; +import org.springframework.security.authentication.InsufficientAuthenticationException; +import org.springframework.stereotype.Component; + +@Component +@Order(Ordered.LOWEST_PRECEDENCE) +public class InsufficientAuthenticationExceptionHandler extends AbstractExceptionHandler { + + public InsufficientAuthenticationExceptionHandler() { + super(InsufficientAuthenticationException.class); + log.info("Created"); + } + + @Override + public HttpStatus getStatus(InsufficientAuthenticationException ex) { + return HttpStatus.FORBIDDEN; + } +} diff --git a/spring-lemon-commons-web/pom.xml b/spring-lemon-commons-web/pom.xml index 2857363c..46f1c386 100644 --- a/spring-lemon-commons-web/pom.xml +++ b/spring-lemon-commons-web/pom.xml @@ -38,7 +38,7 @@ com.naturalprogrammer spring-lemon - 1.0.0.RC7 + 1.0.1 diff --git a/spring-lemon-commons/pom.xml b/spring-lemon-commons/pom.xml index e88a105c..e60b6b28 100644 --- a/spring-lemon-commons/pom.xml +++ b/spring-lemon-commons/pom.xml @@ -39,7 +39,7 @@ com.naturalprogrammer spring-lemon - 1.0.0.RC7 + 1.0.1 diff --git a/spring-lemon-exceptions/pom.xml b/spring-lemon-exceptions/pom.xml index 15778c8a..e1c1ba47 100644 --- a/spring-lemon-exceptions/pom.xml +++ b/spring-lemon-exceptions/pom.xml @@ -39,7 +39,7 @@ com.naturalprogrammer spring-lemon - 1.0.0.RC7 + 1.0.1 diff --git a/spring-lemon-jpa/pom.xml b/spring-lemon-jpa/pom.xml index 8f037824..253a70c3 100644 --- a/spring-lemon-jpa/pom.xml +++ b/spring-lemon-jpa/pom.xml @@ -38,7 +38,7 @@ com.naturalprogrammer spring-lemon - 1.0.0.RC7 + 1.0.1 diff --git a/spring-lemon-reactive/pom.xml b/spring-lemon-reactive/pom.xml index 39c75726..def9ecbb 100644 --- a/spring-lemon-reactive/pom.xml +++ b/spring-lemon-reactive/pom.xml @@ -38,7 +38,7 @@ com.naturalprogrammer spring-lemon - 1.0.0.RC7 + 1.0.1 From 3f390b07f745ee252b08ded57c331a6723756628 Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Fri, 1 Jul 2022 12:26:03 +0530 Subject: [PATCH 112/116] 1.0.2: Spring Boot 2.7.1 Update + JsonPatch update --- lemon-demo-jpa/pom.xml | 2 +- lemon-demo-reactive/pom.xml | 2 +- pom.xml | 4 +-- spring-lemon-commons-jpa/pom.xml | 2 +- spring-lemon-commons-mongo/pom.xml | 2 +- spring-lemon-commons-reactive/pom.xml | 2 +- spring-lemon-commons-web/pom.xml | 2 +- spring-lemon-commons/pom.xml | 6 ++-- .../spring/lemon/commons/util/LecUtils.java | 30 +++++++++---------- spring-lemon-exceptions/pom.xml | 2 +- spring-lemon-jpa/pom.xml | 2 +- spring-lemon-reactive/pom.xml | 2 +- 12 files changed, 29 insertions(+), 29 deletions(-) diff --git a/lemon-demo-jpa/pom.xml b/lemon-demo-jpa/pom.xml index 945adccd..66068e70 100644 --- a/lemon-demo-jpa/pom.xml +++ b/lemon-demo-jpa/pom.xml @@ -14,7 +14,7 @@ com.naturalprogrammer spring-lemon - 1.0.1 + 1.0.2 diff --git a/lemon-demo-reactive/pom.xml b/lemon-demo-reactive/pom.xml index 197b903a..a310142b 100644 --- a/lemon-demo-reactive/pom.xml +++ b/lemon-demo-reactive/pom.xml @@ -13,7 +13,7 @@ com.naturalprogrammer spring-lemon - 1.0.1 + 1.0.2 diff --git a/pom.xml b/pom.xml index b41ef488..676875c5 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.naturalprogrammer spring-lemon - 1.0.1 + 1.0.2 pom ${project.groupId}:${project.artifactId} @@ -40,7 +40,7 @@ org.springframework.boot spring-boot-starter-parent - 2.6.0 + 2.7.1 diff --git a/spring-lemon-commons-jpa/pom.xml b/spring-lemon-commons-jpa/pom.xml index 6a4f7a55..a205789e 100644 --- a/spring-lemon-commons-jpa/pom.xml +++ b/spring-lemon-commons-jpa/pom.xml @@ -38,7 +38,7 @@ com.naturalprogrammer spring-lemon - 1.0.1 + 1.0.2 diff --git a/spring-lemon-commons-mongo/pom.xml b/spring-lemon-commons-mongo/pom.xml index a18dbbec..6c5f2b9f 100644 --- a/spring-lemon-commons-mongo/pom.xml +++ b/spring-lemon-commons-mongo/pom.xml @@ -38,7 +38,7 @@ com.naturalprogrammer spring-lemon - 1.0.1 + 1.0.2 diff --git a/spring-lemon-commons-reactive/pom.xml b/spring-lemon-commons-reactive/pom.xml index dc841ffb..f0623243 100644 --- a/spring-lemon-commons-reactive/pom.xml +++ b/spring-lemon-commons-reactive/pom.xml @@ -38,7 +38,7 @@ com.naturalprogrammer spring-lemon - 1.0.1 + 1.0.2 diff --git a/spring-lemon-commons-web/pom.xml b/spring-lemon-commons-web/pom.xml index 46f1c386..53b0ebc0 100644 --- a/spring-lemon-commons-web/pom.xml +++ b/spring-lemon-commons-web/pom.xml @@ -38,7 +38,7 @@ com.naturalprogrammer spring-lemon - 1.0.1 + 1.0.2 diff --git a/spring-lemon-commons/pom.xml b/spring-lemon-commons/pom.xml index e60b6b28..b1451d4d 100644 --- a/spring-lemon-commons/pom.xml +++ b/spring-lemon-commons/pom.xml @@ -39,7 +39,7 @@ com.naturalprogrammer spring-lemon - 1.0.1 + 1.0.2 @@ -76,9 +76,9 @@ - com.github.fge + com.github.java-json-tools json-patch - 1.9 + 1.13