diff --git a/postman/reactredux.postman_collection.json b/postman/reactredux.postman_collection.json
index f735f1c..990c408 100644
--- a/postman/reactredux.postman_collection.json
+++ b/postman/reactredux.postman_collection.json
@@ -25,11 +25,12 @@
}
],
"url": {
- "raw": "{{baseUrl}}/Content/{{siteId}}?locale=en-US",
+ "raw": "{{reverseProxy}}/api/Content/{{siteId}}?locale=en-US",
"host": [
- "{{baseUrl}}"
+ "{{reverseProxy}}"
],
"path": [
+ "api",
"Content",
"{{siteId}}"
],
@@ -65,12 +66,12 @@
}
],
"url": {
- "raw": "{{baseUrl}}//CategoryItem/{{siteId}}/e154e33f-3cc7-468d-bb66-e0390ddb9ae0",
+ "raw": "{{reverseProxy}}/api/CategoryItem/{{siteId}}/e154e33f-3cc7-468d-bb66-e0390ddb9ae0",
"host": [
- "{{baseUrl}}"
+ "{{reverseProxy}}"
],
"path": [
- "",
+ "api",
"CategoryItem",
"{{siteId}}",
"e154e33f-3cc7-468d-bb66-e0390ddb9ae0"
@@ -96,11 +97,12 @@
}
],
"url": {
- "raw": "{{baseUrl}}/CategoryItem/{{siteId}}?slug=default",
+ "raw": "{{reverseProxy}}/api/CategoryItem/{{siteId}}?slug=default",
"host": [
- "{{baseUrl}}"
+ "{{reverseProxy}}"
],
"path": [
+ "api",
"CategoryItem",
"{{siteId}}"
],
@@ -135,12 +137,12 @@
"raw": "{\r\n \"l10n\": [\r\n {\r\n \"locale\": \"\",\r\n \"slug\": \"guides\",\r\n \"text\": \"Guides\"\r\n }\r\n ]\r\n}"
},
"url": {
- "raw": "{{baseUrl}}//CategoryItem/{{siteId}}",
+ "raw": "{{reverseProxy}}/api/CategoryItem/{{siteId}}",
"host": [
- "{{baseUrl}}"
+ "{{reverseProxy}}"
],
"path": [
- "",
+ "api",
"CategoryItem",
"{{siteId}}"
]
@@ -169,12 +171,12 @@
"raw": "{\r\n \"l10n\": [\r\n {\r\n \"locale\": \"en-US\",\r\n \"slug\": \"guides\",\r\n \"text\": \"Guides\"\r\n },\r\n {\r\n \"locale\": \"it-IT\",\r\n \"slug\": \"guide\",\r\n \"text\": \"Guide\"\r\n }\r\n ]\r\n}"
},
"url": {
- "raw": "{{baseUrl}}//CategoryItem/{{siteId}}/2c50f4de-70f2-4414-aabc-7a0d2eb0e203",
+ "raw": "{{reverseProxy}}/api/CategoryItem/{{siteId}}/2c50f4de-70f2-4414-aabc-7a0d2eb0e203",
"host": [
- "{{baseUrl}}"
+ "{{reverseProxy}}"
],
"path": [
- "",
+ "api",
"CategoryItem",
"{{siteId}}",
"2c50f4de-70f2-4414-aabc-7a0d2eb0e203"
@@ -200,11 +202,12 @@
}
],
"url": {
- "raw": "{{baseUrl}}/CategoryItem/{{siteId}}/e154e33f-3cc7-468d-bb66-e0390ddb9ae0",
+ "raw": "{{reverseProxy}}/api/CategoryItem/{{siteId}}/e154e33f-3cc7-468d-bb66-e0390ddb9ae0",
"host": [
- "{{baseUrl}}"
+ "{{reverseProxy}}"
],
"path": [
+ "api",
"CategoryItem",
"{{siteId}}",
"e154e33f-3cc7-468d-bb66-e0390ddb9ae0"
@@ -235,11 +238,12 @@
}
],
"url": {
- "raw": "{{baseUrl}}/CategoryItems/{{siteId}}",
+ "raw": "{{reverseProxy}}/api/CategoryItems/{{siteId}}",
"host": [
- "{{baseUrl}}"
+ "{{reverseProxy}}"
],
"path": [
+ "api",
"CategoryItems",
"{{siteId}}"
]
@@ -264,11 +268,12 @@
}
],
"url": {
- "raw": "{{baseUrl}}/CategoryItems/{{siteId}}?locale=en-US",
+ "raw": "{{reverseProxy}}/api/CategoryItems/{{siteId}}?locale=en-US",
"host": [
- "{{baseUrl}}"
+ "{{reverseProxy}}"
],
"path": [
+ "api",
"CategoryItems",
"{{siteId}}"
],
@@ -299,11 +304,12 @@
}
],
"url": {
- "raw": "{{baseUrl}}/CategoryItems/{{siteId}}",
+ "raw": "{{reverseProxy}}/api/CategoryItems/{{siteId}}",
"host": [
- "{{baseUrl}}"
+ "{{reverseProxy}}"
],
"path": [
+ "api",
"CategoryItems",
"{{siteId}}"
]
@@ -337,11 +343,12 @@
"raw": "{\r\n \"siteId\": \"404c8232-9048-4519-bfba-6e78dc7005ca\",\r\n \"l10n\": [\r\n {\r\n \"locale\": \"en-US\",\r\n \"slug\": \"shop-catalog-item-05\",\r\n \"description\": \"Lorem ipsum, dolor sit amet consectetur adipisicing elit.\",\r\n \"title\": \"Shop item title\",\r\n \"shortText\": \"Lorem ipsum, dolor sit amet consectetur adipisicing elit. Eaque fugit ratione dicta mollitia. Officiis ad...\",\r\n \"text\": \"
Lorem ipsum, dolor sit amet consectetur adipisicing elit.
\",\r\n \"textFormat\": \"HTML\",\r\n \"plainText\": \"Lorem ipsum, dolor sit amet consectetur adipisicing elit.\",\r\n \"badges\": [\r\n \"sale\"\r\n ]\r\n }\r\n ],\r\n\t\"mediaAttachments\": [\r\n\t {\r\n\t\t\"src\": \"api/Image/450x300/5033d24e-a7c3-4960-ac3c-f396d6773692\",\r\n\t\t\"mediaType\": \"image\",\r\n\t\t\"l10n\": [\r\n {\r\n \"locale\": \"en-US\",\r\n \"alt\": \"...\",\r\n\t\t\t\"target\": \"/title-image\",\r\n\t\t\t\"title\": \"Title image\",\r\n\t\t\t\"description\": \"Title image description.\"\r\n\t }\r\n ]\r\n\t }\r\n\t],\r\n \"author\": \"fdc5aa50-ee68-4bae-a8e6-b8ae2c258f60\",\r\n \"created\": {\r\n \"$date\": \"2022-01-01T00:00:00.000Z\"\r\n },\r\n \"tags\": [\r\n \"react\",\r\n \"redux\",\r\n \"webapi\"\r\n ],\r\n \"brandName\": \"Mongodb Brand & Name\",\r\n \"sku\": \"SKU-05\",\r\n \"rating\": 4.5,\r\n \"price\": 20,\r\n \"newPrice\": 10,\r\n \"quantity\": 100\r\n }"
},
"url": {
- "raw": "{{baseUrl}}/ShopItem/{{siteId}}/SKU-05",
+ "raw": "{{reverseProxy}}/api/ShopItem/{{siteId}}/SKU-05",
"host": [
- "{{baseUrl}}"
+ "{{reverseProxy}}"
],
"path": [
+ "api",
"ShopItem",
"{{siteId}}",
"SKU-05"
@@ -367,12 +374,12 @@
}
],
"url": {
- "raw": "{{baseUrl}}//ShopItem/{{siteId}}/SKU-05",
+ "raw": "{{reverseProxy}}/api/ShopItem/{{siteId}}/SKU-05",
"host": [
- "{{baseUrl}}"
+ "{{reverseProxy}}"
],
"path": [
- "",
+ "api",
"ShopItem",
"{{siteId}}",
"SKU-05"
@@ -398,12 +405,12 @@
}
],
"url": {
- "raw": "{{baseUrl}}/ShopItem/{{siteId}}?slug=shop-catalog-item-05",
+ "raw": "{{reverseProxy}}/api/ShopItem/{{siteId}}?slug=shop-catalog-item-05",
"host": [
- "{{baseUrl}}"
+ "{{reverseProxy}}"
],
"path": [
- "",
+ "api",
"ShopItem",
"{{siteId}}"
],
@@ -438,11 +445,12 @@
"raw": "{\r\n \"siteId\": \"404c8232-9048-4519-bfba-6e78dc7005ca\",\r\n \"l10n\": [\r\n {\r\n \"locale\": \"en-US\",\r\n \"slug\": \"shop-catalog-item-05\",\r\n \"description\": \"Lorem ipsum, dolor sit amet consectetur adipisicing elit.\",\r\n \"title\": \"Shop item title\",\r\n \"shortText\": \"Lorem ipsum, dolor sit amet consectetur adipisicing elit. Eaque fugit ratione dicta mollitia. Officiis ad...\",\r\n \"text\": \"Lorem ipsum, dolor sit amet consectetur adipisicing elit.
\",\r\n \"textFormat\": \"HTML\",\r\n \"plainText\": \"Lorem ipsum, dolor sit amet consectetur adipisicing elit.\",\r\n \"badges\": [\r\n \"sale\"\r\n ]\r\n }\r\n ],\r\n\t\"mediaAttachments\": [\r\n\t {\r\n\t\t\"src\": \"api/Image/450x300/5033d24e-a7c3-4960-ac3c-f396d6773692\",\r\n\t\t\"mediaType\": \"image\",\r\n\t\t\"l10n\": [\r\n {\r\n \"locale\": \"en-US\",\r\n \"alt\": \"...\",\r\n\t\t\t\"target\": \"/title-image\",\r\n\t\t\t\"title\": \"Title image\",\r\n\t\t\t\"description\": \"Title image description.\"\r\n\t }\r\n ]\r\n\t }\r\n\t],\r\n \"author\": \"fdc5aa50-ee68-4bae-a8e6-b8ae2c258f60\",\r\n \"created\": {\r\n \"$date\": \"2022-01-01T00:00:00.000Z\"\r\n },\r\n \"tags\": [\r\n \"react\",\r\n \"redux\",\r\n \"webapi\"\r\n ],\r\n \"categories\": [\r\n \"e154e33f-3cc7-468d-bb66-e0390ddb9ae0\"\r\n ],\r\n \"brandName\": \"Mongodb Brand & Name\",\r\n \"sku\": \"SKU-05\",\r\n \"rating\": 4.5,\r\n \"price\": 20,\r\n \"newPrice\": 10,\r\n \"quantity\": 100\r\n }"
},
"url": {
- "raw": "{{baseUrl}}/ShopItem/{{siteId}}/SKU-05",
+ "raw": "{{reverseProxy}}/api/ShopItem/{{siteId}}/SKU-05",
"host": [
- "{{baseUrl}}"
+ "{{reverseProxy}}"
],
"path": [
+ "api",
"ShopItem",
"{{siteId}}",
"SKU-05"
@@ -468,11 +476,12 @@
}
],
"url": {
- "raw": "{{baseUrl}}/ShopItem/{{siteId}}/SKU-05",
+ "raw": "{{reverseProxy}}/api/ShopItem/{{siteId}}/SKU-05",
"host": [
- "{{baseUrl}}"
+ "{{reverseProxy}}"
],
"path": [
+ "api",
"ShopItem",
"{{siteId}}",
"SKU-05"
@@ -503,11 +512,12 @@
}
],
"url": {
- "raw": "{{baseUrl}}/ShopItems/{{siteId}}?currentPage=1&itemsPerPage=4",
+ "raw": "{{reverseProxy}}/api/ShopItems/{{siteId}}?currentPage=1&itemsPerPage=4",
"host": [
- "{{baseUrl}}"
+ "{{reverseProxy}}"
],
"path": [
+ "api",
"ShopItems",
"{{siteId}}"
],
@@ -542,11 +552,12 @@
}
],
"url": {
- "raw": "{{baseUrl}}/ShopItems/{{siteId}}?currentPage=2&itemsPerPage=2&locale=en-US",
+ "raw": "{{reverseProxy}}/api/ShopItems/{{siteId}}?currentPage=2&itemsPerPage=2&locale=en-US",
"host": [
- "{{baseUrl}}"
+ "{{reverseProxy}}"
],
"path": [
+ "api",
"ShopItems",
"{{siteId}}"
],
@@ -585,11 +596,12 @@
}
],
"url": {
- "raw": "{{baseUrl}}/ShopItems/{{siteId}}",
+ "raw": "{{reverseProxy}}/api/ShopItems/{{siteId}}",
"host": [
- "{{baseUrl}}"
+ "{{reverseProxy}}"
],
"path": [
+ "api",
"ShopItems",
"{{siteId}}"
]
@@ -619,11 +631,12 @@
}
],
"url": {
- "raw": "{{baseUrl}}/ShopCartItem/{{siteId}}/fdc5aa50-ee68-4bae-a8e6-b8ae2c258f60/SKU-04?locale=en-US",
+ "raw": "{{reverseProxy}}/api/ShopCartItem/{{siteId}}/fdc5aa50-ee68-4bae-a8e6-b8ae2c258f60/SKU-04?locale=en-US",
"host": [
- "{{baseUrl}}"
+ "{{reverseProxy}}"
],
"path": [
+ "api",
"ShopCartItem",
"{{siteId}}",
"fdc5aa50-ee68-4bae-a8e6-b8ae2c258f60",
@@ -660,12 +673,12 @@
"raw": "{\r\n \"quantity\": 1\r\n}"
},
"url": {
- "raw": "{{baseUrl}}//ShopCartItem/{{siteId}}/fdc5aa50-ee68-4bae-a8e6-b8ae2c258f60/SKU-05",
+ "raw": "{{reverseProxy}}/api/ShopCartItem/{{siteId}}/fdc5aa50-ee68-4bae-a8e6-b8ae2c258f60/SKU-05",
"host": [
- "{{baseUrl}}"
+ "{{reverseProxy}}"
],
"path": [
- "",
+ "api",
"ShopCartItem",
"{{siteId}}",
"fdc5aa50-ee68-4bae-a8e6-b8ae2c258f60",
@@ -696,11 +709,12 @@
"raw": "{\r\n \"quantity\": 5\r\n}"
},
"url": {
- "raw": "{{baseUrl}}/ShopCartItem/{{siteId}}/fdc5aa50-ee68-4bae-a8e6-b8ae2c258f60/SKU-04",
+ "raw": "{{reverseProxy}}/api/ShopCartItem/{{siteId}}/fdc5aa50-ee68-4bae-a8e6-b8ae2c258f60/SKU-04",
"host": [
- "{{baseUrl}}"
+ "{{reverseProxy}}"
],
"path": [
+ "api",
"ShopCartItem",
"{{siteId}}",
"fdc5aa50-ee68-4bae-a8e6-b8ae2c258f60",
@@ -727,11 +741,12 @@
}
],
"url": {
- "raw": "{{baseUrl}}/ShopCartItem/{{siteId}}/fdc5aa50-ee68-4bae-a8e6-b8ae2c258f60/SKU-04",
+ "raw": "{{reverseProxy}}/api/ShopCartItem/{{siteId}}/fdc5aa50-ee68-4bae-a8e6-b8ae2c258f60/SKU-04",
"host": [
- "{{baseUrl}}"
+ "{{reverseProxy}}"
],
"path": [
+ "api",
"ShopCartItem",
"{{siteId}}",
"fdc5aa50-ee68-4bae-a8e6-b8ae2c258f60",
@@ -763,11 +778,12 @@
}
],
"url": {
- "raw": "{{baseUrl}}/ShopCartItems/{{siteId}}/fdc5aa50-ee68-4bae-a8e6-b8ae2c258f60?locale=en-US",
+ "raw": "{{reverseProxy}}/api/ShopCartItems/{{siteId}}/fdc5aa50-ee68-4bae-a8e6-b8ae2c258f60?locale=en-US",
"host": [
- "{{baseUrl}}"
+ "{{reverseProxy}}"
],
"path": [
+ "api",
"ShopCartItems",
"{{siteId}}",
"fdc5aa50-ee68-4bae-a8e6-b8ae2c258f60"
@@ -799,11 +815,12 @@
}
],
"url": {
- "raw": "{{baseUrl}}/ShopCartItems/{{siteId}}/fdc5aa50-ee68-4bae-a8e6-b8ae2c258f60",
+ "raw": "{{reverseProxy}}/api/ShopCartItems/{{siteId}}/fdc5aa50-ee68-4bae-a8e6-b8ae2c258f60",
"host": [
- "{{baseUrl}}"
+ "{{reverseProxy}}"
],
"path": [
+ "api",
"ShopCartItems",
"{{siteId}}",
"fdc5aa50-ee68-4bae-a8e6-b8ae2c258f60"
@@ -834,11 +851,12 @@
}
],
"url": {
- "raw": "{{baseUrl}}/BlogItem/{{siteId}}/11f2f5f8-1270-4640-b082-c2e7ea8e60b4",
+ "raw": "{{reverseProxy}}/api/BlogItem/{{siteId}}/11f2f5f8-1270-4640-b082-c2e7ea8e60b4",
"host": [
- "{{baseUrl}}"
+ "{{reverseProxy}}"
],
"path": [
+ "api",
"BlogItem",
"{{siteId}}",
"11f2f5f8-1270-4640-b082-c2e7ea8e60b4"
@@ -864,11 +882,12 @@
}
],
"url": {
- "raw": "{{baseUrl}}/BlogItem/{{siteId}}?slug=privacy-terms-and-conditions",
+ "raw": "{{reverseProxy}}/api/BlogItem/{{siteId}}?slug=privacy-terms-and-conditions",
"host": [
- "{{baseUrl}}"
+ "{{reverseProxy}}"
],
"path": [
+ "api",
"BlogItem",
"{{siteId}}"
],
@@ -903,11 +922,12 @@
"raw": "{\r\n\r\n \"l10n\": [\r\n {\r\n \"locale\": \"en-US\",\r\n \"slug\": \"hello-world\",\r\n \"description\": \"Hello world description\",\r\n \"title\": \"Hello world title\",\r\n \"shortText\": \"Hello world short text\",\r\n \"text\": \"Hello World
\",\r\n \"contentType\": \"HTML\",\r\n \"badges\": [\r\n \"post\"\r\n ]\r\n }\r\n ],\r\n \"images\": [\r\n {\r\n \"l10n\": [\r\n {\r\n \"locale\": \"en-US\",\r\n \"alt\": \"...\"\r\n },\r\n {\r\n \"locale\": \"it-IT\",\r\n \"alt\": \"...\"\r\n }\r\n ]\r\n }\r\n ],\r\n \"tags\": [\r\n \"privacy\",\r\n \"terms\"\r\n ],\r\n \"categories\": [\r\n \"e154e33f-3cc7-468d-bb66-e0390ddb9ae0\" \r\n ],\r\n \"familyFriendly\": true\r\n}"
},
"url": {
- "raw": "{{baseUrl}}/BlogItem/{{siteId}}",
+ "raw": "{{reverseProxy}}/api/BlogItem/{{siteId}}",
"host": [
- "{{baseUrl}}"
+ "{{reverseProxy}}"
],
"path": [
+ "api",
"BlogItem",
"{{siteId}}"
]
@@ -936,11 +956,12 @@
"raw": "{\r\n\r\n \"l10n\": [\r\n {\r\n \"locale\": \"en-US\",\r\n \"slug\": \"hello-world\",\r\n \"description\": \"Hello world description\",\r\n \"title\": \"Hello world title\",\r\n \"shortText\": \"Hello world short text\",\r\n \"text\": \"New Hello World
\",\r\n \"contentType\": \"HTML\",\r\n \"badges\": [\r\n \"post\"\r\n ]\r\n }\r\n ],\r\n \"images\": [\r\n {\r\n \"l10n\": [\r\n {\r\n \"locale\": \"en-US\",\r\n \"alt\": \"...\"\r\n },\r\n {\r\n \"locale\": \"it-IT\",\r\n \"alt\": \"...\"\r\n }\r\n ]\r\n }\r\n ],\r\n \"tags\": [\r\n \"privacy\",\r\n \"terms\"\r\n ],\r\n \"categories\": [\r\n \"e154e33f-3cc7-468d-bb66-e0390ddb9ae0\" \r\n ],\r\n \"familyFriendly\": true\r\n}"
},
"url": {
- "raw": "{{baseUrl}}/BlogItem/{{siteId}}/94feda90-ddf6-4717-8879-9c7139e7ff30",
+ "raw": "{{reverseProxy}}/api/BlogItem/{{siteId}}/94feda90-ddf6-4717-8879-9c7139e7ff30",
"host": [
- "{{baseUrl}}"
+ "{{reverseProxy}}"
],
"path": [
+ "api",
"BlogItem",
"{{siteId}}",
"94feda90-ddf6-4717-8879-9c7139e7ff30"
@@ -966,11 +987,12 @@
}
],
"url": {
- "raw": "{{baseUrl}}/BlogItem/{{siteId}}/94feda90-ddf6-4717-8879-9c7139e7ff30",
+ "raw": "{{reverseProxy}}/api/BlogItem/{{siteId}}/94feda90-ddf6-4717-8879-9c7139e7ff30",
"host": [
- "{{baseUrl}}"
+ "{{reverseProxy}}"
],
"path": [
+ "api",
"BlogItem",
"{{siteId}}",
"94feda90-ddf6-4717-8879-9c7139e7ff30"
@@ -1001,11 +1023,12 @@
}
],
"url": {
- "raw": "{{baseUrl}}/BlogItems/{{siteId}}?currentPage=2&itemsPerPage=2",
+ "raw": "{{reverseProxy}}/api/BlogItems/{{siteId}}?currentPage=2&itemsPerPage=2",
"host": [
- "{{baseUrl}}"
+ "{{reverseProxy}}"
],
"path": [
+ "api",
"BlogItems",
"{{siteId}}"
],
@@ -1040,11 +1063,12 @@
}
],
"url": {
- "raw": "{{baseUrl}}/BlogItems/{{siteId}}?currentPage=2&itemsPerPage=2&locale=en-US",
+ "raw": "{{reverseProxy}}/api/BlogItems/{{siteId}}?currentPage=2&itemsPerPage=2&locale=en-US",
"host": [
- "{{baseUrl}}"
+ "{{reverseProxy}}"
],
"path": [
+ "api",
"BlogItems",
"{{siteId}}"
],
@@ -1083,11 +1107,12 @@
}
],
"url": {
- "raw": "{{baseUrl}}/BlogItems/{{siteId}}",
+ "raw": "{{reverseProxy}}/api/BlogItems/{{siteId}}",
"host": [
- "{{baseUrl}}"
+ "{{reverseProxy}}"
],
"path": [
+ "api",
"BlogItems",
"{{siteId}}"
]
@@ -1117,15 +1142,16 @@
}
],
"url": {
- "raw": "{{baseUrl}}/File/{{siteId}}/fdc5aa50-ee68-4bae-a8e6-b8ae2c258f60/4f163ea9-1786-4192-8efa-3b8ea9ca88fa",
+ "raw": "{{reverseProxy}}/api/File/{{siteId}}/fdc5aa50-ee68-4bae-a8e6-b8ae2c258f60/55ecc564-c086-4e77-a8b2-ef32c2a8c280",
"host": [
- "{{baseUrl}}"
+ "{{reverseProxy}}"
],
"path": [
+ "api",
"File",
"{{siteId}}",
"fdc5aa50-ee68-4bae-a8e6-b8ae2c258f60",
- "4f163ea9-1786-4192-8efa-3b8ea9ca88fa"
+ "55ecc564-c086-4e77-a8b2-ef32c2a8c280"
]
}
},
@@ -1158,11 +1184,12 @@
]
},
"url": {
- "raw": "{{baseUrl}}/File/{{siteId}}/fdc5aa50-ee68-4bae-a8e6-b8ae2c258f60",
+ "raw": "{{reverseProxy}}/api/File/{{siteId}}/fdc5aa50-ee68-4bae-a8e6-b8ae2c258f60",
"host": [
- "{{baseUrl}}"
+ "{{reverseProxy}}"
],
"path": [
+ "api",
"File",
"{{siteId}}",
"fdc5aa50-ee68-4bae-a8e6-b8ae2c258f60"
@@ -1188,11 +1215,12 @@
}
],
"url": {
- "raw": "{{baseUrl}}/File/{{siteId}}/fdc5aa50-ee68-4bae-a8e6-b8ae2c258f60/3930ff55-67e1-4763-be59-37407f91e0a9",
+ "raw": "{{reverseProxy}}/api/File/{{siteId}}/fdc5aa50-ee68-4bae-a8e6-b8ae2c258f60/3930ff55-67e1-4763-be59-37407f91e0a9",
"host": [
- "{{baseUrl}}"
+ "{{reverseProxy}}"
],
"path": [
+ "api",
"File",
"{{siteId}}",
"fdc5aa50-ee68-4bae-a8e6-b8ae2c258f60",
@@ -1235,11 +1263,12 @@
]
},
"url": {
- "raw": "{{baseUrl}}/Files/{{siteId}}/fdc5aa50-ee68-4bae-a8e6-b8ae2c258f60",
+ "raw": "{{reverseProxy}}/api/Files/{{siteId}}/fdc5aa50-ee68-4bae-a8e6-b8ae2c258f60",
"host": [
- "{{baseUrl}}"
+ "{{reverseProxy}}"
],
"path": [
+ "api",
"Files",
"{{siteId}}",
"fdc5aa50-ee68-4bae-a8e6-b8ae2c258f60"
@@ -1276,11 +1305,12 @@
]
},
"url": {
- "raw": "{{baseUrl}}/Files/{{siteId}}/fdc5aa50-ee68-4bae-a8e6-b8ae2c258f60",
+ "raw": "{{reverseProxy}}/api/Files/{{siteId}}/fdc5aa50-ee68-4bae-a8e6-b8ae2c258f60",
"host": [
- "{{baseUrl}}"
+ "{{reverseProxy}}"
],
"path": [
+ "api",
"Files",
"{{siteId}}",
"fdc5aa50-ee68-4bae-a8e6-b8ae2c258f60"
@@ -1300,11 +1330,12 @@
"method": "GET",
"header": [],
"url": {
- "raw": "{{baseUrl}}/Image/{{siteId}}/450x300/55ecc564-c086-4e77-a8b2-ef32c2a8c280",
+ "raw": "{{reverseProxy}}/api/Image/{{siteId}}/450x300/55ecc564-c086-4e77-a8b2-ef32c2a8c280",
"host": [
- "{{baseUrl}}"
+ "{{reverseProxy}}"
],
"path": [
+ "api",
"Image",
"{{siteId}}",
"450x300",
@@ -1313,17 +1344,148 @@
}
},
"response": []
+ },
+ {
+ "name": "01-Get YARP",
+ "request": {
+ "method": "GET",
+ "header": [],
+ "url": {
+ "raw": "{{reverseProxy}}/image/{{siteId}}/450x300/55ecc564-c086-4e77-a8b2-ef32c2a8c280",
+ "host": [
+ "{{reverseProxy}}"
+ ],
+ "path": [
+ "image",
+ "{{siteId}}",
+ "450x300",
+ "55ecc564-c086-4e77-a8b2-ef32c2a8c280"
+ ]
+ }
+ },
+ "response": []
+ }
+ ]
+ },
+ {
+ "name": "Password",
+ "item": [
+ {
+ "name": "01-Post",
+ "request": {
+ "method": "POST",
+ "header": [
+ {
+ "key": "Content-Type",
+ "value": "application/json",
+ "type": "default"
+ },
+ {
+ "key": "Accept",
+ "value": "application/json",
+ "type": "default"
+ }
+ ],
+ "body": {
+ "mode": "raw",
+ "raw": "{\r\n \"password\": \"password\"\r\n}"
+ },
+ "url": {
+ "raw": "{{reverseProxy}}/api/Password/{{siteId}}/fdc5aa50-ee68-4bae-a8e6-b8ae2c258f60",
+ "host": [
+ "{{reverseProxy}}"
+ ],
+ "path": [
+ "api",
+ "Password",
+ "{{siteId}}",
+ "fdc5aa50-ee68-4bae-a8e6-b8ae2c258f60"
+ ]
+ }
+ },
+ "response": []
+ }
+ ]
+ },
+ {
+ "name": "Authentication",
+ "item": [
+ {
+ "name": "01-Post",
+ "request": {
+ "method": "POST",
+ "header": [
+ {
+ "key": "Content-Type",
+ "value": "application/json",
+ "type": "default"
+ },
+ {
+ "key": "Accept",
+ "value": "application/json",
+ "type": "default"
+ }
+ ],
+ "body": {
+ "mode": "raw",
+ "raw": "{\r\n \"username\": \"Admin\",\r\n \"password\": \"Password\"\r\n}"
+ },
+ "url": {
+ "raw": "{{reverseProxy}}/api/Authentication/{{siteId}}",
+ "host": [
+ "{{reverseProxy}}"
+ ],
+ "path": [
+ "api",
+ "Authentication",
+ "{{siteId}}"
+ ]
+ }
+ },
+ "response": []
}
]
}
],
+ "auth": {
+ "type": "bearer",
+ "bearer": [
+ {
+ "key": "token",
+ "value": "{{access_token}}",
+ "type": "string"
+ }
+ ]
+ },
"event": [
{
"listen": "prerequest",
"script": {
"type": "text/javascript",
"exec": [
- ""
+ "const postRequest = {",
+ " url: pm.collectionVariables.get(\"tokenEndpoint\"),",
+ " method: \"post\",",
+ " header: {",
+ " \"Content-Type\": \"application/json\",",
+ " \"Accept\": \"application/json\"",
+ " },",
+ " body: {",
+ " mode: \"raw\",",
+ " raw: {",
+ " \"username\": \"Admin\",",
+ " \"password\": \"Password\"",
+ " },",
+ " },",
+ "};",
+ "",
+ "pm.sendRequest(postRequest, (error, response) => {",
+ " if (error) {",
+ " console.log(error);",
+ " } else {",
+ " pm.collectionVariables.set(\"access_token\", response);",
+ " }",
+ "});"
]
}
},
@@ -1339,14 +1501,23 @@
],
"variable": [
{
- "key": "baseUrl",
- "value": "https://localhost:7151/api",
+ "key": "reverseProxy",
+ "value": "https://localhost:7174",
"type": "default"
},
{
"key": "siteId",
"value": "404c8232-9048-4519-bfba-6e78dc7005ca",
"type": "default"
+ },
+ {
+ "key": "tokenEndpoint",
+ "value": "https://localhost:7174/api/Authentication/404c8232-9048-4519-bfba-6e78dc7005ca",
+ "type": "default"
+ },
+ {
+ "key": "access_token",
+ "value": ""
}
]
}
\ No newline at end of file
diff --git a/webapi/Core/Abstractions/DomainObjects/PersonBase.cs b/webapi/Core/Abstractions/DomainObjects/PersonBase.cs
index 9f47e84..aebfd55 100644
--- a/webapi/Core/Abstractions/DomainObjects/PersonBase.cs
+++ b/webapi/Core/Abstractions/DomainObjects/PersonBase.cs
@@ -3,6 +3,6 @@
namespace Core.Abstractions.DomainObjects {
public abstract class PersonBase : DomainObjectBase {
public Guid Id { get; set; }
- public MediaAttachment? Image { get; set; }
+ public Image? Image { get; set; }
}
}
diff --git a/webapi/Core/Abstractions/Models/RequestModelBase.cs b/webapi/Core/Abstractions/Models/RequestModelBase.cs
index 6164b60..26f35ee 100644
--- a/webapi/Core/Abstractions/Models/RequestModelBase.cs
+++ b/webapi/Core/Abstractions/Models/RequestModelBase.cs
@@ -2,6 +2,12 @@
using System.Diagnostics.CodeAnalysis;
namespace Core.Abstractions.Models {
+
+ public abstract class RequestModelBase : ModelBase, IValidatableObject {
+ public abstract IEnumerable Validate(ValidationContext validationContext);
+ }
+
+
public abstract class RequestModelBase : ModelBase, IValidatableObject {
public abstract T ToDomainObject();
public abstract IEnumerable Validate(ValidationContext validationContext);
diff --git a/webapi/Core/Abstractions/ServiceBase.cs b/webapi/Core/Abstractions/ServiceBase.cs
new file mode 100644
index 0000000..0eda579
--- /dev/null
+++ b/webapi/Core/Abstractions/ServiceBase.cs
@@ -0,0 +1,19 @@
+using Microsoft.Extensions.Logging;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Core.Abstractions {
+ public abstract class ServiceBase {
+
+ protected readonly ILogger _logger;
+
+ public ServiceBase(
+ ILogger logger
+ ) {
+ _logger = logger;
+ }
+ }
+}
diff --git a/webapi/Core/Core.csproj b/webapi/Core/Core.csproj
index 27ac386..e984ac7 100644
--- a/webapi/Core/Core.csproj
+++ b/webapi/Core/Core.csproj
@@ -6,4 +6,8 @@
enable
+
+
+
+
diff --git a/webapi/Core/DomainObjects/Image.cs b/webapi/Core/DomainObjects/Image.cs
index d0a640d..01d7ecf 100644
--- a/webapi/Core/DomainObjects/Image.cs
+++ b/webapi/Core/DomainObjects/Image.cs
@@ -6,15 +6,15 @@ namespace Core.DomainObjects {
- public class MediaAttachment : DomainObjectBase {
+ public class Image : DomainObjectBase {
public string Src { get; set; }
- public MediaTypes MediaType { get; set; }
- public List L10n { get; set; }
+
+ public string Alt { get; set; }
public override int GetHashCode() {
int hash = 17;
hash = hash * 23 + Src.GetHashCode();
- hash = hash * 23 + L10n.GetHashCode();
+ hash = hash * 23 + Alt.GetHashCode();
return hash;
}
}
diff --git a/webapi/Core/DomainObjects/MediaAttachment.cs b/webapi/Core/DomainObjects/MediaAttachment.cs
new file mode 100644
index 0000000..e3ba881
--- /dev/null
+++ b/webapi/Core/DomainObjects/MediaAttachment.cs
@@ -0,0 +1,22 @@
+using Core.Abstractions.DomainObjects;
+using Core.DomainObjects.L10n;
+using Core.Enumerations;
+
+namespace Core.DomainObjects {
+
+
+
+ public class MediaAttachment : DomainObjectBase {
+ public string Src { get; set; }
+
+ public MediaTypes MediaType { get; set; }
+ public List L10n { get; set; }
+
+ public override int GetHashCode() {
+ int hash = 17;
+ hash = hash * 23 + Src.GetHashCode();
+ hash = hash * 23 + L10n.GetHashCode();
+ return hash;
+ }
+ }
+}
diff --git a/webapi/Core/DomainObjects/PageSections/TitleSection.cs b/webapi/Core/DomainObjects/PageSections/TitleSection.cs
index 1601ce8..6e4bd0d 100644
--- a/webapi/Core/DomainObjects/PageSections/TitleSection.cs
+++ b/webapi/Core/DomainObjects/PageSections/TitleSection.cs
@@ -2,7 +2,7 @@
namespace Core.DomainObjects.PageSections {
public class TitleSection : PageSectionBase {
- public MediaAttachment? Image { get; set; }
+ public Image? Image { get; set; }
public Link? PrimaryLink { get; set; }
public Link? SecondaryLink { get; set; }
public string? PostedOnBy { get; set; }
diff --git a/webapi/DataProviders/Collections/UserDataProvider.cs b/webapi/DataProviders/Collections/UserDataProvider.cs
new file mode 100644
index 0000000..7d3fde6
--- /dev/null
+++ b/webapi/DataProviders/Collections/UserDataProvider.cs
@@ -0,0 +1,17 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace DataProviders.Collections {
+
+ public interface IUserDataProvider {
+
+ }
+
+ internal class UserDataProvider : IUserDataProvider {
+
+
+ }
+}
diff --git a/webapi/DataProviders/Extensions/ServiceCollectionExtensions.cs b/webapi/DataProviders/Extensions/ServiceCollectionExtensions.cs
index b7e5a13..dc1d34a 100644
--- a/webapi/DataProviders/Extensions/ServiceCollectionExtensions.cs
+++ b/webapi/DataProviders/Extensions/ServiceCollectionExtensions.cs
@@ -26,6 +26,7 @@ namespace DataProviders.Extensions
services.AddSingleton();
services.AddSingleton();
services.AddSingleton();
+ services.AddSingleton();
#endregion
#region Buckets
diff --git a/webapi/ReverseProxy/appsettings.json b/webapi/ReverseProxy/appsettings.json
index 14b4b49..7eb8d1c 100644
--- a/webapi/ReverseProxy/appsettings.json
+++ b/webapi/ReverseProxy/appsettings.json
@@ -12,7 +12,22 @@
"route1": {
"ClusterId": "cluster1",
"Match": {
- "Path": "{**catch-all}"
+ "Path": "api/{**catchall}"
+ }
+ },
+ "route2": {
+ "ClusterId": "cluster1",
+ "Match": {
+ "Path": "image/{**catchall}"
+ },
+ "Transforms": [
+ { "PathPattern": "/api/Image/{**catchall}" }
+ ]
+ },
+ "route3": {
+ "ClusterId": "cluster2",
+ "Match": {
+ "Path": "{**catchall}"
}
}
},
@@ -20,7 +35,14 @@
"cluster1": {
"Destinations": {
"destination1": {
- "Address": "https://example.com/"
+ "Address": "https://localhost:7151/"
+ }
+ }
+ },
+ "cluster2": {
+ "Destinations": {
+ "destination1": {
+ "Address": "http://localhost:3000/"
}
}
}
diff --git a/webapi/Services/HashService/Extensions/ServiceCollectionExtensions.cs b/webapi/Services/HashService/Extensions/ServiceCollectionExtensions.cs
new file mode 100644
index 0000000..540cdbb
--- /dev/null
+++ b/webapi/Services/HashService/Extensions/ServiceCollectionExtensions.cs
@@ -0,0 +1,11 @@
+using Microsoft.Extensions.DependencyInjection;
+
+namespace HashService.Extensions {
+ public static class ServiceCollectionExtensions {
+
+ public static void RegisterHashService(this IServiceCollection services) {
+
+ services.AddSingleton();
+ }
+ }
+}
diff --git a/webapi/Services/HashService/HashService.cs b/webapi/Services/HashService/HashService.cs
index 9f21b2a..87afdee 100644
--- a/webapi/Services/HashService/HashService.cs
+++ b/webapi/Services/HashService/HashService.cs
@@ -2,7 +2,7 @@
using System.Security.Cryptography;
using Microsoft.AspNetCore.Cryptography.KeyDerivation;
-namespace Services {
+namespace HashService {
public interface IHashService {
(string, string) CreateSaltedHash(string value);
@@ -35,6 +35,7 @@ namespace Services {
return (salt, hash);
}
- public bool ValidateHash(string value, string salt, string hash) => CreateHash(value, salt) == hash;
+ public bool ValidateHash(string value, string salt, string hash) =>
+ CreateHash(value, salt) == hash;
}
}
diff --git a/webapi/Services/HashService/HashService.csproj b/webapi/Services/HashService/HashService.csproj
index 0a6de5f..f69d928 100644
--- a/webapi/Services/HashService/HashService.csproj
+++ b/webapi/Services/HashService/HashService.csproj
@@ -1,4 +1,4 @@
-
+
net6.0
@@ -7,7 +7,12 @@
-
-
+
+
+
+
+
+
+
diff --git a/webapi/Services/JWTService/Extensions/ServiceCollectionExtensions.cs b/webapi/Services/JWTService/Extensions/ServiceCollectionExtensions.cs
new file mode 100644
index 0000000..0eb0447
--- /dev/null
+++ b/webapi/Services/JWTService/Extensions/ServiceCollectionExtensions.cs
@@ -0,0 +1,14 @@
+using Microsoft.Extensions.DependencyInjection;
+
+namespace JWTService.Extensions {
+ public static class ServiceCollectionExtensions {
+ public static void RegisterJWTService(this IServiceCollection services, IJWTServiceConfig appSettings) {
+ var config = appSettings.JwtConfig;
+
+ if(config == null) throw new NullReferenceException();
+
+ services.AddSingleton(x => config);
+ services.AddSingleton();
+ }
+ }
+}
diff --git a/webapi/Services/JWTService/IJWTServiceConfig.cs b/webapi/Services/JWTService/IJWTServiceConfig.cs
new file mode 100644
index 0000000..2ccee90
--- /dev/null
+++ b/webapi/Services/JWTService/IJWTServiceConfig.cs
@@ -0,0 +1,17 @@
+using System.IO;
+
+namespace JWTService {
+ public interface IJWTServiceConfig {
+ public JwtConfig? JwtConfig { get; set; }
+ }
+
+ public interface IJwtConfig {
+ public string? Secret { get; set; }
+ public double? Expires { get; set; }
+ }
+
+ public class JwtConfig : IJwtConfig {
+ public string? Secret { get; set; }
+ public double? Expires { get; set; }
+ }
+}
diff --git a/webapi/Services/JWTService/IJWTServiceConfiguration.cs b/webapi/Services/JWTService/IJWTServiceConfiguration.cs
deleted file mode 100644
index 1d4376c..0000000
--- a/webapi/Services/JWTService/IJWTServiceConfiguration.cs
+++ /dev/null
@@ -1,7 +0,0 @@
-using System.IO;
-
-namespace Services {
- public interface IJwtServiceSettings {
- string Secret { get; set; }
- }
-}
diff --git a/webapi/Services/JWTService/JWTService.cs b/webapi/Services/JWTService/JWTService.cs
index 8e0ccb7..b6099db 100644
--- a/webapi/Services/JWTService/JWTService.cs
+++ b/webapi/Services/JWTService/JWTService.cs
@@ -1,51 +1,87 @@
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
-
-
+using Microsoft.Extensions.Logging;
using Microsoft.IdentityModel.Tokens;
-namespace Services {
+namespace JWTService {
- public interface IJwtService {
- string CreateJwtToken(IEnumerable issuer, DateTime expires, string userId, string userEmail, string userName, IEnumerable userRoles);
+ public interface IJWTService {
+ string CreateJwtToken();
JwtSecurityToken ReadJwtToken(string token);
}
- public class JwtService : IJwtService {
- private readonly JwtSecurityTokenHandler _tokenHandler;
- private readonly IJwtServiceSettings _serviceSettings;
+ public class JWTService : IJWTService {
- public JwtService(IJwtServiceSettings serviceSettings) {
- _serviceSettings = serviceSettings;
+ private readonly ILogger _logger;
+
+ private readonly JwtSecurityTokenHandler _tokenHandler;
+ private readonly IJwtConfig _serviceConfig;
+
+ ///
+ ///
+ ///
+ ///
+ public JWTService(
+ ILogger logger,
+ IJwtConfig serviceConfig
+
+ ) {
+ _logger = logger;
+ _serviceConfig = serviceConfig;
_tokenHandler = new JwtSecurityTokenHandler();
}
- public string CreateJwtToken(IEnumerable issuer, DateTime expires, string userId, string userEmail, string userName, IEnumerable userRoles) {
- var key = Convert.FromBase64String(_serviceSettings.Secret);
+ public string? CreateJwtToken() {
+ if (_serviceConfig.Secret == null)
+ return null;
+
+ if (_serviceConfig.Expires == null)
+ return null;
+
+
+ var key = Convert.FromBase64String(_serviceConfig.Secret);
// add roles to claims identity from database
- var claims = new List() {
- new Claim(ClaimTypes.Actor, userId),
- new Claim(ClaimTypes.Email, userEmail),
- new Claim(ClaimTypes.NameIdentifier, userName),
- // new Claim(ClaimTypes.Webpage, issuer)
- };
+ var claims = new List() {};
- foreach (var role in userRoles)
- claims.Add(new Claim(ClaimTypes.Role, role));
-
- foreach (var iss in issuer)
- claims.Add(new Claim(ClaimTypes.Webpage, iss));
var token = _tokenHandler.CreateToken(new SecurityTokenDescriptor {
IssuedAt = DateTime.UtcNow,
Subject = new ClaimsIdentity(claims),
- Expires = expires,
+ Expires = DateTime.UtcNow.AddDays(_serviceConfig.Expires.Value),
SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha512Signature),
});
return _tokenHandler.WriteToken(token);
}
+
+ //public string CreateJwtToken(IEnumerable issuer, DateTime expires, string userId, string userEmail, string userName, IEnumerable userRoles) {
+ // var key = Convert.FromBase64String(_serviceConfig.Secret);
+
+ // // add roles to claims identity from database
+ // var claims = new List() {
+ // new Claim(ClaimTypes.Actor, userId),
+ // new Claim(ClaimTypes.Email, userEmail),
+ // new Claim(ClaimTypes.NameIdentifier, userName),
+ // // new Claim(ClaimTypes.Webpage, issuer)
+ // };
+
+ // foreach (var role in userRoles)
+ // claims.Add(new Claim(ClaimTypes.Role, role));
+
+ // foreach (var iss in issuer)
+ // claims.Add(new Claim(ClaimTypes.Webpage, iss));
+
+ // var token = _tokenHandler.CreateToken(new SecurityTokenDescriptor {
+ // IssuedAt = DateTime.UtcNow,
+ // Subject = new ClaimsIdentity(claims),
+ // Expires = expires,
+ // SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha512Signature),
+ // });
+
+ // return _tokenHandler.WriteToken(token);
+ //}
+
public JwtSecurityToken ReadJwtToken(string token) => _tokenHandler.ReadJwtToken(token);
}
}
diff --git a/webapi/Services/JWTService/JWTService.csproj b/webapi/Services/JWTService/JWTService.csproj
index 9b54a3d..26e8c73 100644
--- a/webapi/Services/JWTService/JWTService.csproj
+++ b/webapi/Services/JWTService/JWTService.csproj
@@ -1,4 +1,4 @@
-
+
net6.0
@@ -7,6 +7,9 @@
+
+
+
diff --git a/webapi/WeatherForecast/Configuration.cs b/webapi/WeatherForecast/Configuration.cs
index ea8dace..2ebf90b 100644
--- a/webapi/WeatherForecast/Configuration.cs
+++ b/webapi/WeatherForecast/Configuration.cs
@@ -1,20 +1,22 @@
using DataProviders;
+using JWTService;
namespace WeatherForecast {
///
///
///
- public class Configuration : IDataProvidersConfig{
+ public class Configuration : IDataProvidersConfig, IJWTServiceConfig {
///
///
///
- public string? Secret { get; set; }
+ public JwtConfig? JwtConfig { get; set; }
///
///
///
public Database? Database { get; set; }
+
}
}
diff --git a/webapi/WeatherForecast/Controllers/AuthenticationController.cs b/webapi/WeatherForecast/Controllers/AuthenticationController.cs
new file mode 100644
index 0000000..e0afe63
--- /dev/null
+++ b/webapi/WeatherForecast/Controllers/AuthenticationController.cs
@@ -0,0 +1,43 @@
+
+using DomainResults.Mvc;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Mvc;
+
+using WeatherForecast.Models.Requests;
+using WeatherForecast.Services;
+
+namespace WeatherForecast.Controllers {
+
+ ///
+ ///
+ ///
+ [AllowAnonymous]
+ [ApiController]
+ [Route("api/[controller]")]
+ public class AuthenticationController : ControllerBase {
+
+ private readonly IAuthenticationService _authenticationService;
+
+ ///
+ ///
+ ///
+ ///
+ public AuthenticationController(
+ IAuthenticationService authenticationService
+ ) {
+ _authenticationService = authenticationService;
+ }
+
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ [HttpPost("{siteId}")]
+ public IActionResult Post([FromRoute] Guid siteId, [FromBody] AuthenticationRequestModel requestData) {
+ var result = _authenticationService.Post(siteId, requestData);
+ return result.ToActionResult();
+ }
+ }
+}
diff --git a/webapi/WeatherForecast/Controllers/BlogItemController.cs b/webapi/WeatherForecast/Controllers/BlogItemController.cs
index fad234d..efa94ea 100644
--- a/webapi/WeatherForecast/Controllers/BlogItemController.cs
+++ b/webapi/WeatherForecast/Controllers/BlogItemController.cs
@@ -12,7 +12,7 @@ namespace WeatherForecast.Controllers {
///
///
///
- [AllowAnonymous]
+ [Authorize]
[ApiController]
[Route("api/[controller]")]
public class BlogItemController : ControllerBase {
diff --git a/webapi/WeatherForecast/Controllers/BlogItemsController.cs b/webapi/WeatherForecast/Controllers/BlogItemsController.cs
index 6230e07..3b0751f 100644
--- a/webapi/WeatherForecast/Controllers/BlogItemsController.cs
+++ b/webapi/WeatherForecast/Controllers/BlogItemsController.cs
@@ -48,6 +48,7 @@ public class BlogItemsController : ControllerBase {
///
///
///
+ [Authorize]
[HttpDelete("{siteId}")]
public IActionResult Delete([FromRoute] Guid siteId) {
var result = _blogItemsService.Delete(siteId);
diff --git a/webapi/WeatherForecast/Controllers/CategoryItemController.cs b/webapi/WeatherForecast/Controllers/CategoryItemController.cs
index a0efb1f..5f52e89 100644
--- a/webapi/WeatherForecast/Controllers/CategoryItemController.cs
+++ b/webapi/WeatherForecast/Controllers/CategoryItemController.cs
@@ -11,7 +11,7 @@ namespace WeatherForecast.Controllers {
///
///
///
- [AllowAnonymous]
+ [Authorize]
[ApiController]
[Route("api/[controller]")]
public class CategoryItemController : ControllerBase {
@@ -56,7 +56,7 @@ namespace WeatherForecast.Controllers {
///
///
///
- ///
+ [AllowAnonymous]
[HttpGet("{siteId}")]
public IActionResult GetSlug([FromRoute] Guid siteId, [FromQuery] string slug) {
var result = _categoryItemService.GetSlug(siteId, slug);
diff --git a/webapi/WeatherForecast/Controllers/CategoryItemsController.cs b/webapi/WeatherForecast/Controllers/CategoryItemsController.cs
index 96270b8..5dcd939 100644
--- a/webapi/WeatherForecast/Controllers/CategoryItemsController.cs
+++ b/webapi/WeatherForecast/Controllers/CategoryItemsController.cs
@@ -10,7 +10,7 @@ namespace WeatherForecast.Controllers {
///
///
///
- [AllowAnonymous]
+ [Authorize]
[ApiController]
[Route("api/[controller]")]
public class CategoryItemsController : ControllerBase {
@@ -44,6 +44,7 @@ namespace WeatherForecast.Controllers {
///
///
///
+ [AllowAnonymous]
[HttpDelete("{siteId}")]
public IActionResult Delete([FromRoute] Guid siteId) {
var result = _categoryItemsService.Delete(siteId);
diff --git a/webapi/WeatherForecast/Controllers/FileController.cs b/webapi/WeatherForecast/Controllers/FileController.cs
index 79c5343..a85ea4d 100644
--- a/webapi/WeatherForecast/Controllers/FileController.cs
+++ b/webapi/WeatherForecast/Controllers/FileController.cs
@@ -9,7 +9,7 @@ namespace WeatherForecast.Controllers {
///
///
///
- [ApiController]
+ [Authorize]
[AllowAnonymous]
[Route("api/[controller]")]
public class FileController : Controller {
diff --git a/webapi/WeatherForecast/Controllers/FilesController.cs b/webapi/WeatherForecast/Controllers/FilesController.cs
index e473552..bda1d78 100644
--- a/webapi/WeatherForecast/Controllers/FilesController.cs
+++ b/webapi/WeatherForecast/Controllers/FilesController.cs
@@ -8,7 +8,7 @@ namespace WeatherForecast.Controllers {
///
///
///
- [ApiController]
+ [Authorize]
[AllowAnonymous]
[Route("api/[controller]")]
public class FilesController : Controller {
diff --git a/webapi/WeatherForecast/Controllers/LoginController.cs b/webapi/WeatherForecast/Controllers/LoginController.cs
deleted file mode 100644
index a76ea2b..0000000
--- a/webapi/WeatherForecast/Controllers/LoginController.cs
+++ /dev/null
@@ -1,31 +0,0 @@
-using Core.Abstractions.Models;
-using Microsoft.AspNetCore.Mvc;
-
-using WeatherForecast.Models;
-
-namespace WeatherForecast.Controllers {
-
-//public class PostLoginRequest : RequestModelBase {
-// public string Username { get; set; }
-// public string Password { get; set; }
-
-//}
-
-
-//[ApiController]
-//[Route("[controller]")]
-//public class LoginController : ControllerBase {
-
-// private readonly ILogger _logger;
-
-// public LoginController(ILogger logger) {
-// _logger = logger;
-// }
-
-// [HttpPost(Name = "Login")]
-// public IActionResult Post([FromBody] PostLoginRequest requestBody) {
-// return BadRequest();
-// }
-
-
-}
diff --git a/webapi/WeatherForecast/Controllers/PasswordController.cs b/webapi/WeatherForecast/Controllers/PasswordController.cs
new file mode 100644
index 0000000..72153d5
--- /dev/null
+++ b/webapi/WeatherForecast/Controllers/PasswordController.cs
@@ -0,0 +1,38 @@
+using DomainResults.Mvc;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Mvc;
+using WeatherForecast.Models.Requests;
+using WeatherForecast.Services;
+
+namespace WeatherForecast.Controllers {
+ ///
+ ///
+ ///
+ [Authorize]
+ [Route("api/[controller]")]
+ [ApiController]
+ public class PasswordController : ControllerBase {
+
+ private readonly IPasswordService _passwordService;
+
+ public PasswordController(
+ IPasswordService passwordService
+ ) {
+ _passwordService = passwordService;
+ }
+
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ [HttpPost("{siteId}/{userId}")]
+ public IActionResult Post([FromRoute] Guid siteId, [FromRoute] Guid userId, [FromBody] PasswordRequestModel requestData) {
+ var result = _passwordService.Post(siteId, userId, requestData);
+ return result.ToActionResult();
+ }
+ }
+}
diff --git a/webapi/WeatherForecast/Controllers/ShopCartItemController.cs b/webapi/WeatherForecast/Controllers/ShopCartItemController.cs
index dd0ac2d..caa1ae5 100644
--- a/webapi/WeatherForecast/Controllers/ShopCartItemController.cs
+++ b/webapi/WeatherForecast/Controllers/ShopCartItemController.cs
@@ -12,7 +12,7 @@ namespace WeatherForecast.Controllers {
///
///
///
- [ApiController]
+ [Authorize]
[AllowAnonymous]
[Route("api/[controller]")]
public class ShopCartItemController : ControllerBase {
diff --git a/webapi/WeatherForecast/Controllers/ShopCartItemsController.cs b/webapi/WeatherForecast/Controllers/ShopCartItemsController.cs
index 0e84366..b467e70 100644
--- a/webapi/WeatherForecast/Controllers/ShopCartItemsController.cs
+++ b/webapi/WeatherForecast/Controllers/ShopCartItemsController.cs
@@ -11,7 +11,7 @@ namespace WeatherForecast.Controllers {
///
///
///
- [ApiController]
+ [Authorize]
[AllowAnonymous]
[Route("api/[controller]")]
public class ShopCartItemsController : ControllerBase {
diff --git a/webapi/WeatherForecast/Controllers/ShopItemController.cs b/webapi/WeatherForecast/Controllers/ShopItemController.cs
index 01de26b..0f61c11 100644
--- a/webapi/WeatherForecast/Controllers/ShopItemController.cs
+++ b/webapi/WeatherForecast/Controllers/ShopItemController.cs
@@ -11,7 +11,7 @@ namespace WeatherForecast.Controllers {
///
///
///
- [AllowAnonymous]
+ [Authorize]
[ApiController]
[Route("api/[controller]")]
public class ShopItemController : ControllerBase {
@@ -59,6 +59,7 @@ namespace WeatherForecast.Controllers {
///
///
///
+ [AllowAnonymous]
[HttpGet("{siteId}")]
public IActionResult GetSlug([FromRoute] Guid siteId, [FromQuery] string slug) {
var result = _shopItemService.GetSlug(siteId, slug);
diff --git a/webapi/WeatherForecast/Controllers/ShopItemsController.cs b/webapi/WeatherForecast/Controllers/ShopItemsController.cs
index b89a615..db9cccc 100644
--- a/webapi/WeatherForecast/Controllers/ShopItemsController.cs
+++ b/webapi/WeatherForecast/Controllers/ShopItemsController.cs
@@ -5,52 +5,53 @@ using DomainResults.Mvc;
using WeatherForecast.Services;
-namespace WeatherForecast.Controllers;
-
-///
-///
-///
-[AllowAnonymous]
-[ApiController]
-[Route("api/[controller]")]
-public class ShopItemsController : ControllerBase {
-
- private readonly IShopItemsService _shopItemsService;
+namespace WeatherForecast.Controllers {
///
///
///
- ///
- public ShopItemsController(
- IShopItemsService shopCatalogService
- ) {
- _shopItemsService = shopCatalogService;
- }
+ [Authorize]
+ [ApiController]
+ [Route("api/[controller]")]
+ public class ShopItemsController : ControllerBase {
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- [HttpGet("{siteId}")]
- public IActionResult Get([FromRoute] Guid siteId, [FromQuery] Guid? category, [FromQuery] int? currentPage, [FromQuery] int? itemsPerPage, [FromQuery] string? locale, [FromQuery] string? searchText) {
- var result = _shopItemsService.Get(siteId, category, currentPage ?? 1, itemsPerPage ?? 8, locale, searchText);
- return result.ToActionResult();
- }
+ private readonly IShopItemsService _shopItemsService;
- ///
- ///
- ///
- ///
- ///
- [HttpDelete("{siteId}")]
- public IActionResult Delete([FromRoute] Guid siteId) {
- var result = _shopItemsService.Delete(siteId);
- return result.ToActionResult();
+ ///
+ ///
+ ///
+ ///
+ public ShopItemsController(
+ IShopItemsService shopCatalogService
+ ) {
+ _shopItemsService = shopCatalogService;
+ }
+
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ [HttpGet("{siteId}")]
+ public IActionResult Get([FromRoute] Guid siteId, [FromQuery] Guid? category, [FromQuery] int? currentPage, [FromQuery] int? itemsPerPage, [FromQuery] string? locale, [FromQuery] string? searchText) {
+ var result = _shopItemsService.Get(siteId, category, currentPage ?? 1, itemsPerPage ?? 8, locale, searchText);
+ return result.ToActionResult();
+ }
+
+ ///
+ ///
+ ///
+ ///
+ ///
+ [HttpDelete("{siteId}")]
+ public IActionResult Delete([FromRoute] Guid siteId) {
+ var result = _shopItemsService.Delete(siteId);
+ return result.ToActionResult();
+ }
}
-}
+}
\ No newline at end of file
diff --git a/webapi/WeatherForecast/Controllers/WeatherForecastController.cs b/webapi/WeatherForecast/Controllers/WeatherForecastController.cs
index e74f658..4167175 100644
--- a/webapi/WeatherForecast/Controllers/WeatherForecastController.cs
+++ b/webapi/WeatherForecast/Controllers/WeatherForecastController.cs
@@ -1,3 +1,4 @@
+using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using WeatherForecast.Models.Responses;
@@ -7,6 +8,7 @@ namespace WeatherForecast.Controllers;
///
///
///
+[AllowAnonymous]
[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase {
diff --git a/webapi/WeatherForecast/Models/Requests/AuthenticationRequestModel.cs b/webapi/WeatherForecast/Models/Requests/AuthenticationRequestModel.cs
new file mode 100644
index 0000000..684b270
--- /dev/null
+++ b/webapi/WeatherForecast/Models/Requests/AuthenticationRequestModel.cs
@@ -0,0 +1,36 @@
+using Core.Abstractions.Models;
+using Core.Enumerations;
+using System.ComponentModel.DataAnnotations;
+
+namespace WeatherForecast.Models.Requests {
+
+ ///
+ ///
+ ///
+ public class AuthenticationRequestModel : RequestModelBase {
+
+ ///
+ ///
+ ///
+ public string? Username { get; set; }
+
+ ///
+ ///
+ ///
+ public string? Password { get; set; }
+
+ ///
+ ///
+ ///
+ ///
+ ///
+ public override IEnumerable Validate(ValidationContext validationContext) {
+ if(string.IsNullOrWhiteSpace(Username))
+ yield return new ValidationResult($"{nameof(Username)} ${Errors.NullOrEmpty}");
+
+ if (string.IsNullOrWhiteSpace(Password))
+ yield return new ValidationResult($"{nameof(Password)} ${Errors.NullOrEmpty}");
+ }
+ }
+}
+
diff --git a/webapi/WeatherForecast/Models/Requests/PasswordRequestModel.cs b/webapi/WeatherForecast/Models/Requests/PasswordRequestModel.cs
new file mode 100644
index 0000000..99fbc5d
--- /dev/null
+++ b/webapi/WeatherForecast/Models/Requests/PasswordRequestModel.cs
@@ -0,0 +1,27 @@
+using Core.Abstractions.Models;
+using Core.Enumerations;
+using System.ComponentModel.DataAnnotations;
+
+namespace WeatherForecast.Models.Requests {
+
+ ///
+ ///
+ ///
+ public class PasswordRequestModel : RequestModelBase {
+
+ ///
+ ///
+ ///
+ public string? Password { get; set; }
+
+ ///
+ ///
+ ///
+ ///
+ ///
+ public override IEnumerable Validate(ValidationContext validationContext) {
+ if (string.IsNullOrWhiteSpace(Password))
+ yield return new ValidationResult($"{nameof(Password)} ${Errors.NullOrEmpty}");
+ }
+ }
+}
diff --git a/webapi/WeatherForecast/Program.cs b/webapi/WeatherForecast/Program.cs
index f3e6bf3..835f2d6 100644
--- a/webapi/WeatherForecast/Program.cs
+++ b/webapi/WeatherForecast/Program.cs
@@ -1,4 +1,5 @@
using Serilog;
+using Serilog.Enrichers.Span;
namespace WeatherForecast {
@@ -24,7 +25,8 @@ namespace WeatherForecast {
Host.CreateDefaultBuilder(args)
.UseSerilog((hostContext, services, configuration) => {
configuration.ReadFrom.Configuration(hostContext.Configuration)
- .Enrich.FromLogContext();
+ .Enrich.FromLogContext()
+ .Enrich.WithSpan();
})
.ConfigureWebHostDefaults(webBuilder => {
webBuilder.UseStartup();
diff --git a/webapi/WeatherForecast/Services/Abstractions/PostItemServiceBase.cs b/webapi/WeatherForecast/Services/Abstractions/PostItemServiceBase.cs
index 192cf63..d12df22 100644
--- a/webapi/WeatherForecast/Services/Abstractions/PostItemServiceBase.cs
+++ b/webapi/WeatherForecast/Services/Abstractions/PostItemServiceBase.cs
@@ -1,4 +1,5 @@
-using DataProviders.Collections;
+using Core.Abstractions;
+using DataProviders.Collections;
using DomainResults.Common;
namespace WeatherForecast.Services.Abstractions {
@@ -6,7 +7,7 @@ namespace WeatherForecast.Services.Abstractions {
///
///
///
- public abstract class PostItemServiceBase {
+ public abstract class PostItemServiceBase : ServiceBase {
///
///
@@ -16,10 +17,12 @@ namespace WeatherForecast.Services.Abstractions {
///
///
///
+ ///
///
public PostItemServiceBase(
+ ILogger logger,
ICategoryDataProvider categoryDataProvider
- ) {
+ ) : base(logger) {
_categoryDataProvider = categoryDataProvider;
}
diff --git a/webapi/WeatherForecast/Services/AutheticationService.cs b/webapi/WeatherForecast/Services/AutheticationService.cs
new file mode 100644
index 0000000..866c617
--- /dev/null
+++ b/webapi/WeatherForecast/Services/AutheticationService.cs
@@ -0,0 +1,66 @@
+using Core.Abstractions;
+using DataProviders.Collections;
+using DomainResults.Common;
+using JWTService;
+using WeatherForecast.Models.Requests;
+
+namespace WeatherForecast.Services {
+
+ ///
+ ///
+ ///
+ public interface IAuthenticationService {
+
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ (string?, IDomainResult) Post(Guid siteId, AuthenticationRequestModel requestData);
+ }
+
+ ///
+ ///
+ ///
+ public class AutheticationService : ServiceBase, IAuthenticationService {
+
+ private readonly IUserDataProvider _userDataProvider;
+ private readonly IJWTService _jwtService;
+
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public AutheticationService (
+ ILogger logger,
+ IUserDataProvider userDataProvider,
+ IJWTService jwtService
+ ) : base(logger) {
+ _userDataProvider = userDataProvider;
+ _jwtService = jwtService;
+ }
+
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public (string?, IDomainResult) Post (Guid siteId, AuthenticationRequestModel requestData) {
+ try {
+ var token = _jwtService.CreateJwtToken();
+
+ return token != null
+ ? IDomainResult.Success(token)
+ : IDomainResult.Failed();
+ }
+ catch (Exception ex) {
+ _logger.LogError("Unhandled exception", ex);
+ return IDomainResult.Failed();
+ }
+ }
+ }
+}
diff --git a/webapi/WeatherForecast/Services/BlogItemService.cs b/webapi/WeatherForecast/Services/BlogItemService.cs
index ed4f743..bc56497 100644
--- a/webapi/WeatherForecast/Services/BlogItemService.cs
+++ b/webapi/WeatherForecast/Services/BlogItemService.cs
@@ -1,16 +1,11 @@
using DomainResults.Common;
-using ExtensionMethods;
-using DataProviders;
-
-using Core.DomainObjects;
-using Core.DomainObjects.Documents;
-using Core.DomainObjects.L10n;
using Core.Enumerations;
+using ExtensionMethods;
+using DataProviders.Collections;
using WeatherForecast.Models.Requests;
using WeatherForecast.Models.Responses;
-using DataProviders.Collections;
using WeatherForecast.Services.Abstractions;
namespace WeatherForecast.Services {
@@ -64,8 +59,8 @@ namespace WeatherForecast.Services {
///
///
///
- public class BlogItemService : PostItemServiceBase, IBlogItemService {
- private readonly ILogger _logger;
+ public class BlogItemService : PostItemServiceBase, IBlogItemService {
+
private readonly IBlogCatalogDataProvider _blogCatalogDataProvider;
///
@@ -78,8 +73,7 @@ namespace WeatherForecast.Services {
ILogger logger,
IBlogCatalogDataProvider blogCatalogDataProvider,
ICategoryDataProvider categoryDataProvider
- ) : base(categoryDataProvider) {
- _logger = logger;
+ ) : base(logger, categoryDataProvider) {
_blogCatalogDataProvider = blogCatalogDataProvider;
}
diff --git a/webapi/WeatherForecast/Services/BlogItemsService.cs b/webapi/WeatherForecast/Services/BlogItemsService.cs
index fde97cc..96b1750 100644
--- a/webapi/WeatherForecast/Services/BlogItemsService.cs
+++ b/webapi/WeatherForecast/Services/BlogItemsService.cs
@@ -1,14 +1,10 @@
using DomainResults.Common;
-using DataProviders;
-
using Core.Abstractions;
-using Core.DomainObjects;
using Core.Enumerations;
+using DataProviders.Collections;
using WeatherForecast.Models.Responses;
-using DataProviders.Collections;
-using Core.DomainObjects.Documents;
namespace WeatherForecast.Services {
@@ -40,9 +36,8 @@ namespace WeatherForecast.Services {
///
///
///
- public class BlogItemsService : IBlogItemsService {
+ public class BlogItemsService : ServiceBase, IBlogItemsService {
- private readonly ILogger _logger;
private readonly IBlogCatalogDataProvider _blogCatalogDataProvider;
private readonly ICategoryDataProvider _categoryDataProvider;
@@ -56,8 +51,7 @@ namespace WeatherForecast.Services {
ILogger logger,
IBlogCatalogDataProvider blogCatalogDataProvider,
ICategoryDataProvider categoryDataProvider
- ) {
- _logger = logger;
+ ) : base(logger) {
_blogCatalogDataProvider = blogCatalogDataProvider;
_categoryDataProvider = categoryDataProvider;
}
diff --git a/webapi/WeatherForecast/Services/CategoryItemService.cs b/webapi/WeatherForecast/Services/CategoryItemService.cs
index 5bf4ed8..6dab5db 100644
--- a/webapi/WeatherForecast/Services/CategoryItemService.cs
+++ b/webapi/WeatherForecast/Services/CategoryItemService.cs
@@ -1,12 +1,12 @@
using DomainResults.Common;
-using DataProviders;
+using DataProviders.Collections;
using Core.Enumerations;
using WeatherForecast.Models.Requests;
using WeatherForecast.Models.Responses;
-using DataProviders.Collections;
+using Core.Abstractions;
namespace WeatherForecast.Services {
@@ -60,9 +60,8 @@ namespace WeatherForecast.Services {
///
///
///
- public class CategoryItemService : ICategoryItemService {
+ public class CategoryItemService : ServiceBase, ICategoryItemService {
- private readonly ILogger _logger;
private readonly ICategoryDataProvider _categoryDataProvider;
///
@@ -73,8 +72,7 @@ namespace WeatherForecast.Services {
public CategoryItemService(
ILogger logger,
ICategoryDataProvider categoryDataProvider
- ) {
- _logger = logger;
+ ) : base(logger) {
_categoryDataProvider = categoryDataProvider;
}
diff --git a/webapi/WeatherForecast/Services/CategoryItemsService.cs b/webapi/WeatherForecast/Services/CategoryItemsService.cs
index 393de15..bb18750 100644
--- a/webapi/WeatherForecast/Services/CategoryItemsService.cs
+++ b/webapi/WeatherForecast/Services/CategoryItemsService.cs
@@ -1,12 +1,12 @@
using DomainResults.Common;
-using DataProviders;
+using DataProviders.Collections;
using Core.Abstractions;
using Core.Enumerations;
using WeatherForecast.Models.Responses;
-using DataProviders.Collections;
+
namespace WeatherForecast.Services {
@@ -34,9 +34,8 @@ namespace WeatherForecast.Services {
///
///
///
- public class CategoryItemsService : ICategoryItemsService {
+ public class CategoryItemsService : ServiceBase, ICategoryItemsService {
- private readonly ILogger _logger;
private readonly ICategoryDataProvider _categoryDataProvider;
///
@@ -47,8 +46,7 @@ namespace WeatherForecast.Services {
public CategoryItemsService(
ILogger logger,
ICategoryDataProvider categoryDataProvider
- ) {
- _logger = logger;
+ ) : base(logger) {
_categoryDataProvider = categoryDataProvider;
}
diff --git a/webapi/WeatherForecast/Services/ContentService.cs b/webapi/WeatherForecast/Services/ContentService.cs
index b138718..cca8425 100644
--- a/webapi/WeatherForecast/Services/ContentService.cs
+++ b/webapi/WeatherForecast/Services/ContentService.cs
@@ -3,6 +3,7 @@
using DataProviders.Collections;
using WeatherForecast.Models.Responses;
+using Core.Abstractions;
namespace WeatherForecast.Services {
@@ -23,9 +24,8 @@ namespace WeatherForecast.Services {
///
///
///
- public class ContentService : IContentService {
+ public class ContentService : ServiceBase, IContentService {
- private readonly ILogger _logger;
private readonly IContentDataProvider _contentDataProvider;
///
@@ -36,8 +36,7 @@ namespace WeatherForecast.Services {
public ContentService(
ILogger logger,
IContentDataProvider contentDataprovider
- ) {
- _logger = logger;
+ ) : base(logger) {
_contentDataProvider = contentDataprovider;
}
diff --git a/webapi/WeatherForecast/Services/FileService.cs b/webapi/WeatherForecast/Services/FileService.cs
index 8e4da78..127cf37 100644
--- a/webapi/WeatherForecast/Services/FileService.cs
+++ b/webapi/WeatherForecast/Services/FileService.cs
@@ -1,6 +1,8 @@
-using DataProviders;
+using DomainResults.Common;
+
+using DataProviders;
using DataProviders.Buckets;
-using DomainResults.Common;
+using Core.Abstractions;
namespace WeatherForecast.Services {
@@ -40,9 +42,8 @@ namespace WeatherForecast.Services {
///
///
///
- public class FileService : IFileService {
+ public class FileService : ServiceBase, IFileService {
- private readonly ILogger _logger;
private readonly IFilesService _filesService;
private readonly IImageBucketDataProvider _imageBucketDataProvider;
@@ -53,11 +54,10 @@ namespace WeatherForecast.Services {
///
///
public FileService(
- ILogger logger,
+ ILogger logger,
IFilesService filesService,
IImageBucketDataProvider imageBucketDataProvider
- ) {
- _logger = logger;
+ ) : base(logger) {
_filesService = filesService;
_imageBucketDataProvider = imageBucketDataProvider;
}
diff --git a/webapi/WeatherForecast/Services/FilesService.cs b/webapi/WeatherForecast/Services/FilesService.cs
index e3cb55b..062c662 100644
--- a/webapi/WeatherForecast/Services/FilesService.cs
+++ b/webapi/WeatherForecast/Services/FilesService.cs
@@ -1,7 +1,10 @@
-using DataProviders;
+using DomainResults.Common;
+
+using DataProviders;
using DataProviders.Buckets;
-using DomainResults.Common;
+
using FileSecurityService;
+using Core.Abstractions;
namespace WeatherForecast.Services {
@@ -31,9 +34,8 @@ namespace WeatherForecast.Services {
///
///
///
- public class FilesService : IFilesService {
+ public class FilesService : ServiceBase, IFilesService {
- private readonly ILogger _logger;
private readonly IFileSecurityService _fileSecurityService;
private readonly IImageBucketDataProvider _imageBucketDataProvider;
@@ -46,8 +48,7 @@ namespace WeatherForecast.Services {
ILogger logger,
IFileSecurityService fileSecurityService,
IImageBucketDataProvider imageBucketDataProvider
- ) {
- _logger = logger;
+ ) : base(logger) {
_fileSecurityService = fileSecurityService;
_imageBucketDataProvider = imageBucketDataProvider;
}
diff --git a/webapi/WeatherForecast/Services/ImageService.cs b/webapi/WeatherForecast/Services/ImageService.cs
index b331401..9973cd3 100644
--- a/webapi/WeatherForecast/Services/ImageService.cs
+++ b/webapi/WeatherForecast/Services/ImageService.cs
@@ -1,10 +1,12 @@
-
+using DomainResults.Common;
+
using DataProviders;
using DataProviders.Buckets;
using DataProviders.Collections;
-using DomainResults.Common;
+
using ImageProvider;
using ImageProvider.Fonts;
+using Core.Abstractions;
namespace WeatherForecast.Services {
@@ -26,9 +28,8 @@ namespace WeatherForecast.Services {
///
///
///
- public class ImageService : IImageService {
+ public class ImageService : ServiceBase, IImageService {
- private readonly ILogger _logger;
private readonly IImageBucketDataProvider _imageBucketDataProvider;
private readonly IImageProvider _imageProvider;
private readonly IContentDataProvider _contentDataProvider;
@@ -44,9 +45,7 @@ namespace WeatherForecast.Services {
IImageBucketDataProvider imageBucketDataProvider,
IImageProvider imageProvider,
IContentDataProvider contentDataProvider
-
- ) {
- _logger = logger;
+ ) : base(logger) {
_imageBucketDataProvider = imageBucketDataProvider;
_imageProvider = imageProvider;
_contentDataProvider = contentDataProvider;
diff --git a/webapi/WeatherForecast/Services/PasswordService.cs b/webapi/WeatherForecast/Services/PasswordService.cs
new file mode 100644
index 0000000..d1c89fa
--- /dev/null
+++ b/webapi/WeatherForecast/Services/PasswordService.cs
@@ -0,0 +1,73 @@
+using DomainResults.Common;
+
+using DataProviders.Collections;
+
+using HashService;
+using JWTService;
+using WeatherForecast.Models.Requests;
+using Core.Abstractions;
+
+namespace WeatherForecast.Services {
+ ///
+ ///
+ ///
+ public interface IPasswordService {
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ (Guid?, IDomainResult) Post(Guid siteId, Guid userId, PasswordRequestModel requestData);
+ }
+
+ ///
+ ///
+ ///
+ public class PasswordService : ServiceBase, IPasswordService {
+
+ private readonly IHashService _hashService;
+ private readonly IUserDataProvider _userDataProvider;
+
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public PasswordService(
+ ILogger logger,
+ IHashService hashService,
+
+ IUserDataProvider userDataProvider
+ ) : base(logger) {
+ _hashService = hashService;
+
+ _userDataProvider = userDataProvider;
+ }
+
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public (Guid?, IDomainResult) Post(Guid siteId, Guid userId, PasswordRequestModel requestData) {
+ try {
+
+
+ var (salt, hash) = _hashService.CreateSaltedHash(requestData.Password);
+
+
+
+ return IDomainResult.Success(Guid.NewGuid());
+ }
+ catch (Exception ex) {
+ _logger.LogError("Unhandled exception", ex);
+ return IDomainResult.Failed();
+ }
+ }
+ }
+}
diff --git a/webapi/WeatherForecast/Services/ShopCartItemService.cs b/webapi/WeatherForecast/Services/ShopCartItemService.cs
index 5956275..7bdd911 100644
--- a/webapi/WeatherForecast/Services/ShopCartItemService.cs
+++ b/webapi/WeatherForecast/Services/ShopCartItemService.cs
@@ -58,9 +58,8 @@ namespace WeatherForecast.Services {
///
///
///
- public class ShopCartItemService : IShopCartItemService {
+ public class ShopCartItemService : ServiceBase, IShopCartItemService {
- private readonly ILogger _logger;
private readonly IShopCatalogDataProvider _shopCatalogDataProvider;
private readonly IShopCartDataProvider _shopCartDataProvider;
@@ -74,8 +73,7 @@ namespace WeatherForecast.Services {
ILogger logger,
IShopCatalogDataProvider shopCatalogDataProvider,
IShopCartDataProvider shopCartDataprovider
- ) {
- _logger = logger;
+ ) : base(logger) {
_shopCatalogDataProvider = shopCatalogDataProvider;
_shopCartDataProvider = shopCartDataprovider;
}
diff --git a/webapi/WeatherForecast/Services/ShopCartItemsService.cs b/webapi/WeatherForecast/Services/ShopCartItemsService.cs
index 13e82b6..8ef8ae1 100644
--- a/webapi/WeatherForecast/Services/ShopCartItemsService.cs
+++ b/webapi/WeatherForecast/Services/ShopCartItemsService.cs
@@ -1,12 +1,11 @@
using DomainResults.Common;
-using DataProviders;
+using DataProviders.Collections;
using Core.Enumerations;
using Core.Abstractions;
using WeatherForecast.Models.Responses;
-using DataProviders.Collections;
namespace WeatherForecast.Services {
@@ -36,9 +35,8 @@ namespace WeatherForecast.Services {
///
///
///
- public class ShopCartItemsService : IShopCartItemsService {
+ public class ShopCartItemsService : ServiceBase, IShopCartItemsService {
- private readonly ILogger _logger;
private readonly IShopCatalogDataProvider _shopCatalogDataProvider;
private readonly IShopCartDataProvider _shopCartDataProvider;
@@ -52,8 +50,7 @@ namespace WeatherForecast.Services {
ILogger logger,
IShopCatalogDataProvider shopCatalogDataProvider,
IShopCartDataProvider shopCartDataprovider
- ) {
- _logger = logger;
+ ) : base(logger) {
_shopCatalogDataProvider = shopCatalogDataProvider;
_shopCartDataProvider = shopCartDataprovider;
}
diff --git a/webapi/WeatherForecast/Services/ShopItemService.cs b/webapi/WeatherForecast/Services/ShopItemService.cs
index 2fe03a0..ea1e5c3 100644
--- a/webapi/WeatherForecast/Services/ShopItemService.cs
+++ b/webapi/WeatherForecast/Services/ShopItemService.cs
@@ -1,13 +1,13 @@
using DomainResults.Common;
+using DataProviders.Collections;
+
using ExtensionMethods;
using Core.Enumerations;
using WeatherForecast.Models;
using WeatherForecast.Models.Requests;
-using DataProviders.Collections;
-using Core.DomainObjects.Documents;
using WeatherForecast.Services.Abstractions;
namespace WeatherForecast.Services {
@@ -63,9 +63,8 @@ namespace WeatherForecast.Services {
///
///
///
- public class ShopItemService : PostItemServiceBase, IShopItemService {
+ public class ShopItemService : PostItemServiceBase, IShopItemService {
- private readonly ILogger _logger;
private readonly IShopCatalogDataProvider _shopCatalogDataProvider;
///
@@ -78,8 +77,7 @@ namespace WeatherForecast.Services {
ILogger logger,
IShopCatalogDataProvider shopCatalogDataProvider,
ICategoryDataProvider categoryDataProvider
- ) : base(categoryDataProvider) {
- _logger = logger;
+ ) : base(logger, categoryDataProvider) {
_shopCatalogDataProvider = shopCatalogDataProvider;
}
diff --git a/webapi/WeatherForecast/Services/ShopItemsService.cs b/webapi/WeatherForecast/Services/ShopItemsService.cs
index 25a205a..3353ce3 100644
--- a/webapi/WeatherForecast/Services/ShopItemsService.cs
+++ b/webapi/WeatherForecast/Services/ShopItemsService.cs
@@ -1,15 +1,12 @@
using DomainResults.Common;
-using DataProviders;
+using DataProviders.Collections;
using Core.Abstractions;
-using Core.DomainObjects;
using Core.Enumerations;
using WeatherForecast.Models;
using WeatherForecast.Models.Responses;
-using DataProviders.Collections;
-using Core.DomainObjects.Documents;
namespace WeatherForecast.Services {
@@ -41,8 +38,8 @@ namespace WeatherForecast.Services {
///
///
///
- public class ShopItemsService : IShopItemsService {
- private readonly ILogger _logger;
+ public class ShopItemsService : ServiceBase, IShopItemsService {
+
private readonly IShopCatalogDataProvider _shopCatalogDataProvider;
private readonly ICategoryDataProvider _categoryDataProvider;
@@ -56,8 +53,7 @@ namespace WeatherForecast.Services {
ILogger logger,
IShopCatalogDataProvider shopCatalogDataprovider,
ICategoryDataProvider categoryDataProvider
- ) {
- _logger = logger;
+ ) : base(logger) {
_shopCatalogDataProvider = shopCatalogDataprovider;
_categoryDataProvider = categoryDataProvider;
}
diff --git a/webapi/WeatherForecast/Startup.cs b/webapi/WeatherForecast/Startup.cs
index c2d8c57..e305ed1 100644
--- a/webapi/WeatherForecast/Startup.cs
+++ b/webapi/WeatherForecast/Startup.cs
@@ -8,6 +8,8 @@ using DataProviders.Extensions;
using System.Text.Json.Serialization;
using FileSecurityService.Extensions;
using ImageProvider.Extensions;
+using JWTService.Extensions;
+using HashService.Extensions;
namespace WeatherForecast {
@@ -52,7 +54,7 @@ namespace WeatherForecast {
options.JsonSerializerOptions.DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull);
#region configure jwt authentication
- if (appSettings.Secret != null) {
+ if (appSettings.JwtConfig?.Secret != null) {
services.AddAuthentication(options => {
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
@@ -61,7 +63,7 @@ namespace WeatherForecast {
options.SaveToken = true;
options.TokenValidationParameters = new TokenValidationParameters {
ValidateIssuerSigningKey = true,
- IssuerSigningKey = new SymmetricSecurityKey(Convert.FromBase64String(appSettings.Secret)),
+ IssuerSigningKey = new SymmetricSecurityKey(Convert.FromBase64String(appSettings.JwtConfig.Secret)),
ValidateIssuer = false,
ValidateAudience = false
};
@@ -85,10 +87,14 @@ namespace WeatherForecast {
services.AddScoped();
services.AddScoped();
services.AddScoped();
+ services.AddScoped();
+ services.AddScoped();
services.RegisterDataproviders(appSettings);
services.RegisterFileSecurityService();
services.RegisterImageProvider();
+ services.RegisterJWTService(appSettings);
+ services.RegisterHashService();
#region Swagger
services.ConfigureSwaggerGen(options => {
diff --git a/webapi/WeatherForecast/WeatherForecast.csproj b/webapi/WeatherForecast/WeatherForecast.csproj
index d424e55..a147823 100644
--- a/webapi/WeatherForecast/WeatherForecast.csproj
+++ b/webapi/WeatherForecast/WeatherForecast.csproj
@@ -16,6 +16,7 @@
+
@@ -29,7 +30,9 @@
+
+
diff --git a/webapi/WeatherForecast/appsettings.json b/webapi/WeatherForecast/appsettings.json
index 5693491..33b44e7 100644
--- a/webapi/WeatherForecast/appsettings.json
+++ b/webapi/WeatherForecast/appsettings.json
@@ -8,14 +8,18 @@
"Name": "Console",
"Args": {
"restrictedToMinimumLevel": "Information",
- "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level}] ({SourceContext}.{Method}) {Message}{NewLine}{Exception}"
+ "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} Level=[{Level}] SpanId=[{SpanId}] ({SourceContext}.{Method}) {Message}{NewLine}{Exception}"
}
}
]
},
"AllowedHosts": "*",
"Configuration": {
- "Secret": "TUlJQ1d3SUJBQUtCZ0djczU2dnIzTWRwa0VYczYvYjIyemxMWlhSaFdrSWtyN0dqUHB4ZkNpQk9FU2Q3L2VxcA==",
+ "JwtConfig": {
+ "Secret": "TUlJQ1d3SUJBQUtCZ0djczU2dnIzTWRwa0VYczYvYjIyemxMWlhSaFdrSWtyN0dqUHB4ZkNpQk9FU2Q3L2VxcA==",
+ "Expires": "365"
+ },
+
"Database": {
"ConnectionString": "mongodb://localhost:27017"