(refactor): service base and log spanId

This commit is contained in:
Maksym Sadovnychyy 2022-09-16 22:55:47 +02:00
parent 697c7692d0
commit 750263d466
55 changed files with 893 additions and 301 deletions

View File

@ -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\": \"<p>Lorem ipsum, dolor sit amet consectetur adipisicing elit.</p>\",\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\": \"<p>Lorem ipsum, dolor sit amet consectetur adipisicing elit.</p>\",\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\": \"<p>Hello World</p>\",\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\": \"<p>New Hello World</p>\",\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": ""
}
]
}

View File

@ -3,6 +3,6 @@
namespace Core.Abstractions.DomainObjects {
public abstract class PersonBase<T> : DomainObjectBase<T> {
public Guid Id { get; set; }
public MediaAttachment? Image { get; set; }
public Image? Image { get; set; }
}
}

View File

@ -2,6 +2,12 @@
using System.Diagnostics.CodeAnalysis;
namespace Core.Abstractions.Models {
public abstract class RequestModelBase : ModelBase, IValidatableObject {
public abstract IEnumerable<ValidationResult> Validate(ValidationContext validationContext);
}
public abstract class RequestModelBase<T> : ModelBase, IValidatableObject {
public abstract T ToDomainObject();
public abstract IEnumerable<ValidationResult> Validate(ValidationContext validationContext);

View File

@ -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<T> {
protected readonly ILogger<T> _logger;
public ServiceBase(
ILogger<T> logger
) {
_logger = logger;
}
}
}

View File

@ -6,4 +6,8 @@
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="6.0.2" />
</ItemGroup>
</Project>

View File

@ -6,15 +6,15 @@ namespace Core.DomainObjects {
public class MediaAttachment : DomainObjectBase<MediaAttachment> {
public class Image : DomainObjectBase<MediaAttachment> {
public string Src { get; set; }
public MediaTypes MediaType { get; set; }
public List<MediaAttachmentL10n> 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;
}
}

View File

@ -0,0 +1,22 @@
using Core.Abstractions.DomainObjects;
using Core.DomainObjects.L10n;
using Core.Enumerations;
namespace Core.DomainObjects {
public class MediaAttachment : DomainObjectBase<MediaAttachment> {
public string Src { get; set; }
public MediaTypes MediaType { get; set; }
public List<MediaAttachmentL10n> L10n { get; set; }
public override int GetHashCode() {
int hash = 17;
hash = hash * 23 + Src.GetHashCode();
hash = hash * 23 + L10n.GetHashCode();
return hash;
}
}
}

View File

@ -2,7 +2,7 @@
namespace Core.DomainObjects.PageSections {
public class TitleSection : PageSectionBase<TitleSection> {
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; }

View File

@ -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 {
}
}

View File

@ -26,6 +26,7 @@ namespace DataProviders.Extensions
services.AddSingleton<IShopCartDataProvider, ShopCartDataProvider>();
services.AddSingleton<ICategoryDataProvider, CategoryDataProvider>();
services.AddSingleton<IBlogCatalogDataProvider, BlogCatalogDataProvider>();
services.AddSingleton<IUserDataProvider, UserDataProvider>();
#endregion
#region Buckets

View File

@ -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/"
}
}
}

View File

@ -0,0 +1,11 @@
using Microsoft.Extensions.DependencyInjection;
namespace HashService.Extensions {
public static class ServiceCollectionExtensions {
public static void RegisterHashService(this IServiceCollection services) {
services.AddSingleton<IHashService, HashService>();
}
}
}

View File

@ -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;
}
}

View File

@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
@ -7,7 +7,12 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Cryptography.KeyDerivation" Version="6.0.5" />
</ItemGroup>
<PackageReference Include="DomainResult.Common" Version="3.0.0" />
<PackageReference Include="Microsoft.AspNetCore.Cryptography.KeyDerivation" Version="6.0.8" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="6.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="6.0.0" />
</ItemGroup>
</Project>

View File

@ -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<IJwtConfig>(x => config);
services.AddSingleton<IJWTService, JWTService>();
}
}
}

View File

@ -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; }
}
}

View File

@ -1,7 +0,0 @@
using System.IO;
namespace Services {
public interface IJwtServiceSettings {
string Secret { get; set; }
}
}

View File

@ -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<string> issuer, DateTime expires, string userId, string userEmail, string userName, IEnumerable<string> 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<JWTService> _logger;
private readonly JwtSecurityTokenHandler _tokenHandler;
private readonly IJwtConfig _serviceConfig;
/// <summary>
///
/// </summary>
/// <param name="serviceConfig"></param>
public JWTService(
ILogger<JWTService> logger,
IJwtConfig serviceConfig
) {
_logger = logger;
_serviceConfig = serviceConfig;
_tokenHandler = new JwtSecurityTokenHandler();
}
public string CreateJwtToken(IEnumerable<string> issuer, DateTime expires, string userId, string userEmail, string userName, IEnumerable<string> 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<Claim>() {
new Claim(ClaimTypes.Actor, userId),
new Claim(ClaimTypes.Email, userEmail),
new Claim(ClaimTypes.NameIdentifier, userName),
// new Claim(ClaimTypes.Webpage, issuer)
};
var claims = new List<Claim>() {};
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<string> issuer, DateTime expires, string userId, string userEmail, string userName, IEnumerable<string> userRoles) {
// var key = Convert.FromBase64String(_serviceConfig.Secret);
// // add roles to claims identity from database
// var claims = new List<Claim>() {
// 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);
}
}

View File

@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
@ -7,6 +7,9 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="DomainResult.Common" Version="3.0.0" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="6.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="6.0.0" />
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="6.18.0" />
</ItemGroup>

View File

@ -1,20 +1,22 @@
using DataProviders;
using JWTService;
namespace WeatherForecast {
/// <summary>
///
/// </summary>
public class Configuration : IDataProvidersConfig{
public class Configuration : IDataProvidersConfig, IJWTServiceConfig {
/// <summary>
///
/// </summary>
public string? Secret { get; set; }
public JwtConfig? JwtConfig { get; set; }
/// <summary>
///
/// </summary>
public Database? Database { get; set; }
}
}

View File

@ -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 {
/// <summary>
///
/// </summary>
[AllowAnonymous]
[ApiController]
[Route("api/[controller]")]
public class AuthenticationController : ControllerBase {
private readonly IAuthenticationService _authenticationService;
/// <summary>
///
/// </summary>
/// <param name="authenticationService"></param>
public AuthenticationController(
IAuthenticationService authenticationService
) {
_authenticationService = authenticationService;
}
/// <summary>
///
/// </summary>
/// <param name="siteId"></param>
/// <param name="requestData"></param>
/// <returns></returns>
[HttpPost("{siteId}")]
public IActionResult Post([FromRoute] Guid siteId, [FromBody] AuthenticationRequestModel requestData) {
var result = _authenticationService.Post(siteId, requestData);
return result.ToActionResult();
}
}
}

View File

@ -12,7 +12,7 @@ namespace WeatherForecast.Controllers {
/// <summary>
///
/// </summary>
[AllowAnonymous]
[Authorize]
[ApiController]
[Route("api/[controller]")]
public class BlogItemController : ControllerBase {

View File

@ -48,6 +48,7 @@ public class BlogItemsController : ControllerBase {
/// </summary>
/// <param name="siteId"></param>
/// <returns></returns>
[Authorize]
[HttpDelete("{siteId}")]
public IActionResult Delete([FromRoute] Guid siteId) {
var result = _blogItemsService.Delete(siteId);

View File

@ -11,7 +11,7 @@ namespace WeatherForecast.Controllers {
/// <summary>
///
/// </summary>
[AllowAnonymous]
[Authorize]
[ApiController]
[Route("api/[controller]")]
public class CategoryItemController : ControllerBase {
@ -56,7 +56,7 @@ namespace WeatherForecast.Controllers {
/// </summary>
/// <param name="siteId"></param>
/// <param name="slug"></param>
/// <returns></returns>
[AllowAnonymous]
[HttpGet("{siteId}")]
public IActionResult GetSlug([FromRoute] Guid siteId, [FromQuery] string slug) {
var result = _categoryItemService.GetSlug(siteId, slug);

View File

@ -10,7 +10,7 @@ namespace WeatherForecast.Controllers {
/// <summary>
///
/// </summary>
[AllowAnonymous]
[Authorize]
[ApiController]
[Route("api/[controller]")]
public class CategoryItemsController : ControllerBase {
@ -44,6 +44,7 @@ namespace WeatherForecast.Controllers {
/// </summary>
/// <param name="siteId"></param>
/// <returns></returns>
[AllowAnonymous]
[HttpDelete("{siteId}")]
public IActionResult Delete([FromRoute] Guid siteId) {
var result = _categoryItemsService.Delete(siteId);

View File

@ -9,7 +9,7 @@ namespace WeatherForecast.Controllers {
/// <summary>
///
/// </summary>
[ApiController]
[Authorize]
[AllowAnonymous]
[Route("api/[controller]")]
public class FileController : Controller {

View File

@ -8,7 +8,7 @@ namespace WeatherForecast.Controllers {
/// <summary>
///
/// </summary>
[ApiController]
[Authorize]
[AllowAnonymous]
[Route("api/[controller]")]
public class FilesController : Controller {

View File

@ -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<LoginController> _logger;
// public LoginController(ILogger<LoginController> logger) {
// _logger = logger;
// }
// [HttpPost(Name = "Login")]
// public IActionResult Post([FromBody] PostLoginRequest requestBody) {
// return BadRequest();
// }
}

View File

@ -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 {
/// <summary>
///
/// </summary>
[Authorize]
[Route("api/[controller]")]
[ApiController]
public class PasswordController : ControllerBase {
private readonly IPasswordService _passwordService;
public PasswordController(
IPasswordService passwordService
) {
_passwordService = passwordService;
}
/// <summary>
///
/// </summary>
/// <param name="siteId"></param>
/// <param name="userId"></param>
/// <param name="requestData"></param>
/// <returns></returns>
[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();
}
}
}

View File

@ -12,7 +12,7 @@ namespace WeatherForecast.Controllers {
/// <summary>
///
/// </summary>
[ApiController]
[Authorize]
[AllowAnonymous]
[Route("api/[controller]")]
public class ShopCartItemController : ControllerBase {

View File

@ -11,7 +11,7 @@ namespace WeatherForecast.Controllers {
/// <summary>
///
/// </summary>
[ApiController]
[Authorize]
[AllowAnonymous]
[Route("api/[controller]")]
public class ShopCartItemsController : ControllerBase {

View File

@ -11,7 +11,7 @@ namespace WeatherForecast.Controllers {
/// <summary>
///
/// </summary>
[AllowAnonymous]
[Authorize]
[ApiController]
[Route("api/[controller]")]
public class ShopItemController : ControllerBase {
@ -59,6 +59,7 @@ namespace WeatherForecast.Controllers {
/// <param name="siteId"></param>
/// <param name="slug"></param>
/// <returns></returns>
[AllowAnonymous]
[HttpGet("{siteId}")]
public IActionResult GetSlug([FromRoute] Guid siteId, [FromQuery] string slug) {
var result = _shopItemService.GetSlug(siteId, slug);

View File

@ -5,52 +5,53 @@ using DomainResults.Mvc;
using WeatherForecast.Services;
namespace WeatherForecast.Controllers;
/// <summary>
///
/// </summary>
[AllowAnonymous]
[ApiController]
[Route("api/[controller]")]
public class ShopItemsController : ControllerBase {
private readonly IShopItemsService _shopItemsService;
namespace WeatherForecast.Controllers {
/// <summary>
///
/// </summary>
/// <param name="shopCatalogService"></param>
public ShopItemsController(
IShopItemsService shopCatalogService
) {
_shopItemsService = shopCatalogService;
}
[Authorize]
[ApiController]
[Route("api/[controller]")]
public class ShopItemsController : ControllerBase {
/// <summary>
///
/// </summary>
/// <param name="siteId"></param>
/// <param name="category"></param>
/// <param name="currentPage"></param>
/// <param name="itemsPerPage"></param>
/// <param name="locale"></param>
/// <param name="searchText"></param>
/// <returns></returns>
[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;
/// <summary>
///
/// </summary>
/// <param name="siteId"></param>
/// <returns></returns>
[HttpDelete("{siteId}")]
public IActionResult Delete([FromRoute] Guid siteId) {
var result = _shopItemsService.Delete(siteId);
return result.ToActionResult();
/// <summary>
///
/// </summary>
/// <param name="shopCatalogService"></param>
public ShopItemsController(
IShopItemsService shopCatalogService
) {
_shopItemsService = shopCatalogService;
}
/// <summary>
///
/// </summary>
/// <param name="siteId"></param>
/// <param name="category"></param>
/// <param name="currentPage"></param>
/// <param name="itemsPerPage"></param>
/// <param name="locale"></param>
/// <param name="searchText"></param>
/// <returns></returns>
[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();
}
/// <summary>
///
/// </summary>
/// <param name="siteId"></param>
/// <returns></returns>
[HttpDelete("{siteId}")]
public IActionResult Delete([FromRoute] Guid siteId) {
var result = _shopItemsService.Delete(siteId);
return result.ToActionResult();
}
}
}
}

View File

@ -1,3 +1,4 @@
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using WeatherForecast.Models.Responses;
@ -7,6 +8,7 @@ namespace WeatherForecast.Controllers;
/// <summary>
///
/// </summary>
[AllowAnonymous]
[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase {

View File

@ -0,0 +1,36 @@
using Core.Abstractions.Models;
using Core.Enumerations;
using System.ComponentModel.DataAnnotations;
namespace WeatherForecast.Models.Requests {
/// <summary>
///
/// </summary>
public class AuthenticationRequestModel : RequestModelBase {
/// <summary>
///
/// </summary>
public string? Username { get; set; }
/// <summary>
///
/// </summary>
public string? Password { get; set; }
/// <summary>
///
/// </summary>
/// <param name="validationContext"></param>
/// <returns></returns>
public override IEnumerable<ValidationResult> 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}");
}
}
}

View File

@ -0,0 +1,27 @@
using Core.Abstractions.Models;
using Core.Enumerations;
using System.ComponentModel.DataAnnotations;
namespace WeatherForecast.Models.Requests {
/// <summary>
///
/// </summary>
public class PasswordRequestModel : RequestModelBase {
/// <summary>
///
/// </summary>
public string? Password { get; set; }
/// <summary>
///
/// </summary>
/// <param name="validationContext"></param>
/// <returns></returns>
public override IEnumerable<ValidationResult> Validate(ValidationContext validationContext) {
if (string.IsNullOrWhiteSpace(Password))
yield return new ValidationResult($"{nameof(Password)} ${Errors.NullOrEmpty}");
}
}
}

View File

@ -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<Startup>();

View File

@ -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 {
/// <summary>
///
/// </summary>
public abstract class PostItemServiceBase {
public abstract class PostItemServiceBase<T> : ServiceBase<T> {
/// <summary>
///
@ -16,10 +17,12 @@ namespace WeatherForecast.Services.Abstractions {
/// <summary>
///
/// </summary>
/// <param name="logger"></param>
/// <param name="categoryDataProvider"></param>
public PostItemServiceBase(
ILogger<T> logger,
ICategoryDataProvider categoryDataProvider
) {
) : base(logger) {
_categoryDataProvider = categoryDataProvider;
}

View File

@ -0,0 +1,66 @@
using Core.Abstractions;
using DataProviders.Collections;
using DomainResults.Common;
using JWTService;
using WeatherForecast.Models.Requests;
namespace WeatherForecast.Services {
/// <summary>
///
/// </summary>
public interface IAuthenticationService {
/// <summary>
///
/// </summary>
/// <param name="siteId"></param>
/// <param name="requestData"></param>
/// <returns></returns>
(string?, IDomainResult) Post(Guid siteId, AuthenticationRequestModel requestData);
}
/// <summary>
///
/// </summary>
public class AutheticationService : ServiceBase<AutheticationService>, IAuthenticationService {
private readonly IUserDataProvider _userDataProvider;
private readonly IJWTService _jwtService;
/// <summary>
///
/// </summary>
/// <param name="logger"></param>
/// <param name="userDataProvider"></param>
/// <param name="jwtService"></param>
public AutheticationService (
ILogger<AutheticationService> logger,
IUserDataProvider userDataProvider,
IJWTService jwtService
) : base(logger) {
_userDataProvider = userDataProvider;
_jwtService = jwtService;
}
/// <summary>
///
/// </summary>
/// <param name="siteId"></param>
/// <param name="requestData"></param>
/// <returns></returns>
public (string?, IDomainResult) Post (Guid siteId, AuthenticationRequestModel requestData) {
try {
var token = _jwtService.CreateJwtToken();
return token != null
? IDomainResult.Success(token)
: IDomainResult.Failed<string?>();
}
catch (Exception ex) {
_logger.LogError("Unhandled exception", ex);
return IDomainResult.Failed<string?>();
}
}
}
}

View File

@ -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 {
/// <summary>
///
/// </summary>
public class BlogItemService : PostItemServiceBase, IBlogItemService {
private readonly ILogger<BlogItemService> _logger;
public class BlogItemService : PostItemServiceBase<BlogItemService>, IBlogItemService {
private readonly IBlogCatalogDataProvider _blogCatalogDataProvider;
/// <summary>
@ -78,8 +73,7 @@ namespace WeatherForecast.Services {
ILogger<BlogItemService> logger,
IBlogCatalogDataProvider blogCatalogDataProvider,
ICategoryDataProvider categoryDataProvider
) : base(categoryDataProvider) {
_logger = logger;
) : base(logger, categoryDataProvider) {
_blogCatalogDataProvider = blogCatalogDataProvider;
}

View File

@ -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 {
/// <summary>
///
/// </summary>
public class BlogItemsService : IBlogItemsService {
public class BlogItemsService : ServiceBase<BlogItemsService>, IBlogItemsService {
private readonly ILogger<BlogItemsService> _logger;
private readonly IBlogCatalogDataProvider _blogCatalogDataProvider;
private readonly ICategoryDataProvider _categoryDataProvider;
@ -56,8 +51,7 @@ namespace WeatherForecast.Services {
ILogger<BlogItemsService> logger,
IBlogCatalogDataProvider blogCatalogDataProvider,
ICategoryDataProvider categoryDataProvider
) {
_logger = logger;
) : base(logger) {
_blogCatalogDataProvider = blogCatalogDataProvider;
_categoryDataProvider = categoryDataProvider;
}

View File

@ -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 {
/// <summary>
///
/// </summary>
public class CategoryItemService : ICategoryItemService {
public class CategoryItemService : ServiceBase<CategoryItemService>, ICategoryItemService {
private readonly ILogger<CategoryItemService> _logger;
private readonly ICategoryDataProvider _categoryDataProvider;
/// <summary>
@ -73,8 +72,7 @@ namespace WeatherForecast.Services {
public CategoryItemService(
ILogger<CategoryItemService> logger,
ICategoryDataProvider categoryDataProvider
) {
_logger = logger;
) : base(logger) {
_categoryDataProvider = categoryDataProvider;
}

View File

@ -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 {
/// <summary>
///
/// </summary>
public class CategoryItemsService : ICategoryItemsService {
public class CategoryItemsService : ServiceBase<CategoryItemsService>, ICategoryItemsService {
private readonly ILogger<CategoryItemsService> _logger;
private readonly ICategoryDataProvider _categoryDataProvider;
/// <summary>
@ -47,8 +46,7 @@ namespace WeatherForecast.Services {
public CategoryItemsService(
ILogger<CategoryItemsService> logger,
ICategoryDataProvider categoryDataProvider
) {
_logger = logger;
) : base(logger) {
_categoryDataProvider = categoryDataProvider;
}

View File

@ -3,6 +3,7 @@
using DataProviders.Collections;
using WeatherForecast.Models.Responses;
using Core.Abstractions;
namespace WeatherForecast.Services {
@ -23,9 +24,8 @@ namespace WeatherForecast.Services {
/// <summary>
///
/// </summary>
public class ContentService : IContentService {
public class ContentService : ServiceBase<ContentService>, IContentService {
private readonly ILogger<ContentService> _logger;
private readonly IContentDataProvider _contentDataProvider;
/// <summary>
@ -36,8 +36,7 @@ namespace WeatherForecast.Services {
public ContentService(
ILogger<ContentService> logger,
IContentDataProvider contentDataprovider
) {
_logger = logger;
) : base(logger) {
_contentDataProvider = contentDataprovider;
}

View File

@ -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 {
/// <summary>
///
/// </summary>
public class FileService : IFileService {
public class FileService : ServiceBase<FileService>, IFileService {
private readonly ILogger<FilesService> _logger;
private readonly IFilesService _filesService;
private readonly IImageBucketDataProvider _imageBucketDataProvider;
@ -53,11 +54,10 @@ namespace WeatherForecast.Services {
/// <param name="filesService"></param>
/// <param name="imageBucketDataProvider"></param>
public FileService(
ILogger<FilesService> logger,
ILogger<FileService> logger,
IFilesService filesService,
IImageBucketDataProvider imageBucketDataProvider
) {
_logger = logger;
) : base(logger) {
_filesService = filesService;
_imageBucketDataProvider = imageBucketDataProvider;
}

View File

@ -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 {
/// <summary>
///
/// </summary>
public class FilesService : IFilesService {
public class FilesService : ServiceBase<FilesService>, IFilesService {
private readonly ILogger<FilesService> _logger;
private readonly IFileSecurityService _fileSecurityService;
private readonly IImageBucketDataProvider _imageBucketDataProvider;
@ -46,8 +48,7 @@ namespace WeatherForecast.Services {
ILogger<FilesService> logger,
IFileSecurityService fileSecurityService,
IImageBucketDataProvider imageBucketDataProvider
) {
_logger = logger;
) : base(logger) {
_fileSecurityService = fileSecurityService;
_imageBucketDataProvider = imageBucketDataProvider;
}

View File

@ -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 {
/// <summary>
///
/// </summary>
public class ImageService : IImageService {
public class ImageService : ServiceBase<ImageService>, IImageService {
private readonly ILogger<ImageService> _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;

View File

@ -0,0 +1,73 @@
using DomainResults.Common;
using DataProviders.Collections;
using HashService;
using JWTService;
using WeatherForecast.Models.Requests;
using Core.Abstractions;
namespace WeatherForecast.Services {
/// <summary>
///
/// </summary>
public interface IPasswordService {
/// <summary>
///
/// </summary>
/// <param name="siteId"></param>
/// <param name="userId"></param>
/// <param name="password"></param>
/// <returns></returns>
(Guid?, IDomainResult) Post(Guid siteId, Guid userId, PasswordRequestModel requestData);
}
/// <summary>
///
/// </summary>
public class PasswordService : ServiceBase<PasswordService>, IPasswordService {
private readonly IHashService _hashService;
private readonly IUserDataProvider _userDataProvider;
/// <summary>
///
/// </summary>
/// <param name="logger"></param>
/// <param name="hashService"></param>
/// <param name="jwtService"></param>
/// <param name="userDataProvider"></param>
public PasswordService(
ILogger<PasswordService> logger,
IHashService hashService,
IUserDataProvider userDataProvider
) : base(logger) {
_hashService = hashService;
_userDataProvider = userDataProvider;
}
/// <summary>
///
/// </summary>
/// <param name="userName"></param>
/// <param name="password"></param>
/// <returns></returns>
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<Guid?>();
}
}
}
}

View File

@ -58,9 +58,8 @@ namespace WeatherForecast.Services {
/// <summary>
///
/// </summary>
public class ShopCartItemService : IShopCartItemService {
public class ShopCartItemService : ServiceBase<ShopCartItemService>, IShopCartItemService {
private readonly ILogger<ShopCartItemService> _logger;
private readonly IShopCatalogDataProvider _shopCatalogDataProvider;
private readonly IShopCartDataProvider _shopCartDataProvider;
@ -74,8 +73,7 @@ namespace WeatherForecast.Services {
ILogger<ShopCartItemService> logger,
IShopCatalogDataProvider shopCatalogDataProvider,
IShopCartDataProvider shopCartDataprovider
) {
_logger = logger;
) : base(logger) {
_shopCatalogDataProvider = shopCatalogDataProvider;
_shopCartDataProvider = shopCartDataprovider;
}

View File

@ -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 {
/// <summary>
///
/// </summary>
public class ShopCartItemsService : IShopCartItemsService {
public class ShopCartItemsService : ServiceBase<ShopCartItemsService>, IShopCartItemsService {
private readonly ILogger<ShopCartItemsService> _logger;
private readonly IShopCatalogDataProvider _shopCatalogDataProvider;
private readonly IShopCartDataProvider _shopCartDataProvider;
@ -52,8 +50,7 @@ namespace WeatherForecast.Services {
ILogger<ShopCartItemsService> logger,
IShopCatalogDataProvider shopCatalogDataProvider,
IShopCartDataProvider shopCartDataprovider
) {
_logger = logger;
) : base(logger) {
_shopCatalogDataProvider = shopCatalogDataProvider;
_shopCartDataProvider = shopCartDataprovider;
}

View File

@ -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 {
/// <summary>
///
/// </summary>
public class ShopItemService : PostItemServiceBase, IShopItemService {
public class ShopItemService : PostItemServiceBase<ShopItemService>, IShopItemService {
private readonly ILogger<ShopItemService> _logger;
private readonly IShopCatalogDataProvider _shopCatalogDataProvider;
/// <summary>
@ -78,8 +77,7 @@ namespace WeatherForecast.Services {
ILogger<ShopItemService> logger,
IShopCatalogDataProvider shopCatalogDataProvider,
ICategoryDataProvider categoryDataProvider
) : base(categoryDataProvider) {
_logger = logger;
) : base(logger, categoryDataProvider) {
_shopCatalogDataProvider = shopCatalogDataProvider;
}

View File

@ -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 {
/// <summary>
///
/// </summary>
public class ShopItemsService : IShopItemsService {
private readonly ILogger<ShopItemsService> _logger;
public class ShopItemsService : ServiceBase<ShopItemsService>, IShopItemsService {
private readonly IShopCatalogDataProvider _shopCatalogDataProvider;
private readonly ICategoryDataProvider _categoryDataProvider;
@ -56,8 +53,7 @@ namespace WeatherForecast.Services {
ILogger<ShopItemsService> logger,
IShopCatalogDataProvider shopCatalogDataprovider,
ICategoryDataProvider categoryDataProvider
) {
_logger = logger;
) : base(logger) {
_shopCatalogDataProvider = shopCatalogDataprovider;
_categoryDataProvider = categoryDataProvider;
}

View File

@ -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<IFileService, FileService>();
services.AddScoped<IFilesService, FilesService>();
services.AddScoped<IImageService, ImageService>();
services.AddScoped<IPasswordService, PasswordService>();
services.AddScoped<IAuthenticationService, AutheticationService>();
services.RegisterDataproviders(appSettings);
services.RegisterFileSecurityService();
services.RegisterImageProvider();
services.RegisterJWTService(appSettings);
services.RegisterHashService();
#region Swagger
services.ConfigureSwaggerGen(options => {

View File

@ -16,6 +16,7 @@
<PackageReference Include="DomainResult" Version="3.0.0" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="6.0.5" />
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.14.0" />
<PackageReference Include="Serilog.Enrichers.Span" Version="2.3.0" />
<PackageReference Include="Serilog.Expressions" Version="3.4.0" />
<PackageReference Include="Serilog.Extensions.Hosting" Version="5.0.1" />
<PackageReference Include="Serilog.Extensions.Logging" Version="3.1.0" />
@ -29,7 +30,9 @@
<ProjectReference Include="..\DataProviders\DataProviders.csproj" />
<ProjectReference Include="..\Extensions\Extensions.csproj" />
<ProjectReference Include="..\Services\FileSecurityService\FileSecurityService.csproj" />
<ProjectReference Include="..\Services\HashService\HashService.csproj" />
<ProjectReference Include="..\Services\ImageProvider\ImageProvider.csproj" />
<ProjectReference Include="..\Services\JWTService\JWTService.csproj" />
</ItemGroup>
</Project>

View File

@ -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"