(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": { "url": {
"raw": "{{baseUrl}}/Content/{{siteId}}?locale=en-US", "raw": "{{reverseProxy}}/api/Content/{{siteId}}?locale=en-US",
"host": [ "host": [
"{{baseUrl}}" "{{reverseProxy}}"
], ],
"path": [ "path": [
"api",
"Content", "Content",
"{{siteId}}" "{{siteId}}"
], ],
@ -65,12 +66,12 @@
} }
], ],
"url": { "url": {
"raw": "{{baseUrl}}//CategoryItem/{{siteId}}/e154e33f-3cc7-468d-bb66-e0390ddb9ae0", "raw": "{{reverseProxy}}/api/CategoryItem/{{siteId}}/e154e33f-3cc7-468d-bb66-e0390ddb9ae0",
"host": [ "host": [
"{{baseUrl}}" "{{reverseProxy}}"
], ],
"path": [ "path": [
"", "api",
"CategoryItem", "CategoryItem",
"{{siteId}}", "{{siteId}}",
"e154e33f-3cc7-468d-bb66-e0390ddb9ae0" "e154e33f-3cc7-468d-bb66-e0390ddb9ae0"
@ -96,11 +97,12 @@
} }
], ],
"url": { "url": {
"raw": "{{baseUrl}}/CategoryItem/{{siteId}}?slug=default", "raw": "{{reverseProxy}}/api/CategoryItem/{{siteId}}?slug=default",
"host": [ "host": [
"{{baseUrl}}" "{{reverseProxy}}"
], ],
"path": [ "path": [
"api",
"CategoryItem", "CategoryItem",
"{{siteId}}" "{{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}" "raw": "{\r\n \"l10n\": [\r\n {\r\n \"locale\": \"\",\r\n \"slug\": \"guides\",\r\n \"text\": \"Guides\"\r\n }\r\n ]\r\n}"
}, },
"url": { "url": {
"raw": "{{baseUrl}}//CategoryItem/{{siteId}}", "raw": "{{reverseProxy}}/api/CategoryItem/{{siteId}}",
"host": [ "host": [
"{{baseUrl}}" "{{reverseProxy}}"
], ],
"path": [ "path": [
"", "api",
"CategoryItem", "CategoryItem",
"{{siteId}}" "{{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}" "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": { "url": {
"raw": "{{baseUrl}}//CategoryItem/{{siteId}}/2c50f4de-70f2-4414-aabc-7a0d2eb0e203", "raw": "{{reverseProxy}}/api/CategoryItem/{{siteId}}/2c50f4de-70f2-4414-aabc-7a0d2eb0e203",
"host": [ "host": [
"{{baseUrl}}" "{{reverseProxy}}"
], ],
"path": [ "path": [
"", "api",
"CategoryItem", "CategoryItem",
"{{siteId}}", "{{siteId}}",
"2c50f4de-70f2-4414-aabc-7a0d2eb0e203" "2c50f4de-70f2-4414-aabc-7a0d2eb0e203"
@ -200,11 +202,12 @@
} }
], ],
"url": { "url": {
"raw": "{{baseUrl}}/CategoryItem/{{siteId}}/e154e33f-3cc7-468d-bb66-e0390ddb9ae0", "raw": "{{reverseProxy}}/api/CategoryItem/{{siteId}}/e154e33f-3cc7-468d-bb66-e0390ddb9ae0",
"host": [ "host": [
"{{baseUrl}}" "{{reverseProxy}}"
], ],
"path": [ "path": [
"api",
"CategoryItem", "CategoryItem",
"{{siteId}}", "{{siteId}}",
"e154e33f-3cc7-468d-bb66-e0390ddb9ae0" "e154e33f-3cc7-468d-bb66-e0390ddb9ae0"
@ -235,11 +238,12 @@
} }
], ],
"url": { "url": {
"raw": "{{baseUrl}}/CategoryItems/{{siteId}}", "raw": "{{reverseProxy}}/api/CategoryItems/{{siteId}}",
"host": [ "host": [
"{{baseUrl}}" "{{reverseProxy}}"
], ],
"path": [ "path": [
"api",
"CategoryItems", "CategoryItems",
"{{siteId}}" "{{siteId}}"
] ]
@ -264,11 +268,12 @@
} }
], ],
"url": { "url": {
"raw": "{{baseUrl}}/CategoryItems/{{siteId}}?locale=en-US", "raw": "{{reverseProxy}}/api/CategoryItems/{{siteId}}?locale=en-US",
"host": [ "host": [
"{{baseUrl}}" "{{reverseProxy}}"
], ],
"path": [ "path": [
"api",
"CategoryItems", "CategoryItems",
"{{siteId}}" "{{siteId}}"
], ],
@ -299,11 +304,12 @@
} }
], ],
"url": { "url": {
"raw": "{{baseUrl}}/CategoryItems/{{siteId}}", "raw": "{{reverseProxy}}/api/CategoryItems/{{siteId}}",
"host": [ "host": [
"{{baseUrl}}" "{{reverseProxy}}"
], ],
"path": [ "path": [
"api",
"CategoryItems", "CategoryItems",
"{{siteId}}" "{{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 }" "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": { "url": {
"raw": "{{baseUrl}}/ShopItem/{{siteId}}/SKU-05", "raw": "{{reverseProxy}}/api/ShopItem/{{siteId}}/SKU-05",
"host": [ "host": [
"{{baseUrl}}" "{{reverseProxy}}"
], ],
"path": [ "path": [
"api",
"ShopItem", "ShopItem",
"{{siteId}}", "{{siteId}}",
"SKU-05" "SKU-05"
@ -367,12 +374,12 @@
} }
], ],
"url": { "url": {
"raw": "{{baseUrl}}//ShopItem/{{siteId}}/SKU-05", "raw": "{{reverseProxy}}/api/ShopItem/{{siteId}}/SKU-05",
"host": [ "host": [
"{{baseUrl}}" "{{reverseProxy}}"
], ],
"path": [ "path": [
"", "api",
"ShopItem", "ShopItem",
"{{siteId}}", "{{siteId}}",
"SKU-05" "SKU-05"
@ -398,12 +405,12 @@
} }
], ],
"url": { "url": {
"raw": "{{baseUrl}}/ShopItem/{{siteId}}?slug=shop-catalog-item-05", "raw": "{{reverseProxy}}/api/ShopItem/{{siteId}}?slug=shop-catalog-item-05",
"host": [ "host": [
"{{baseUrl}}" "{{reverseProxy}}"
], ],
"path": [ "path": [
"", "api",
"ShopItem", "ShopItem",
"{{siteId}}" "{{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 }" "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": { "url": {
"raw": "{{baseUrl}}/ShopItem/{{siteId}}/SKU-05", "raw": "{{reverseProxy}}/api/ShopItem/{{siteId}}/SKU-05",
"host": [ "host": [
"{{baseUrl}}" "{{reverseProxy}}"
], ],
"path": [ "path": [
"api",
"ShopItem", "ShopItem",
"{{siteId}}", "{{siteId}}",
"SKU-05" "SKU-05"
@ -468,11 +476,12 @@
} }
], ],
"url": { "url": {
"raw": "{{baseUrl}}/ShopItem/{{siteId}}/SKU-05", "raw": "{{reverseProxy}}/api/ShopItem/{{siteId}}/SKU-05",
"host": [ "host": [
"{{baseUrl}}" "{{reverseProxy}}"
], ],
"path": [ "path": [
"api",
"ShopItem", "ShopItem",
"{{siteId}}", "{{siteId}}",
"SKU-05" "SKU-05"
@ -503,11 +512,12 @@
} }
], ],
"url": { "url": {
"raw": "{{baseUrl}}/ShopItems/{{siteId}}?currentPage=1&itemsPerPage=4", "raw": "{{reverseProxy}}/api/ShopItems/{{siteId}}?currentPage=1&itemsPerPage=4",
"host": [ "host": [
"{{baseUrl}}" "{{reverseProxy}}"
], ],
"path": [ "path": [
"api",
"ShopItems", "ShopItems",
"{{siteId}}" "{{siteId}}"
], ],
@ -542,11 +552,12 @@
} }
], ],
"url": { "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": [ "host": [
"{{baseUrl}}" "{{reverseProxy}}"
], ],
"path": [ "path": [
"api",
"ShopItems", "ShopItems",
"{{siteId}}" "{{siteId}}"
], ],
@ -585,11 +596,12 @@
} }
], ],
"url": { "url": {
"raw": "{{baseUrl}}/ShopItems/{{siteId}}", "raw": "{{reverseProxy}}/api/ShopItems/{{siteId}}",
"host": [ "host": [
"{{baseUrl}}" "{{reverseProxy}}"
], ],
"path": [ "path": [
"api",
"ShopItems", "ShopItems",
"{{siteId}}" "{{siteId}}"
] ]
@ -619,11 +631,12 @@
} }
], ],
"url": { "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": [ "host": [
"{{baseUrl}}" "{{reverseProxy}}"
], ],
"path": [ "path": [
"api",
"ShopCartItem", "ShopCartItem",
"{{siteId}}", "{{siteId}}",
"fdc5aa50-ee68-4bae-a8e6-b8ae2c258f60", "fdc5aa50-ee68-4bae-a8e6-b8ae2c258f60",
@ -660,12 +673,12 @@
"raw": "{\r\n \"quantity\": 1\r\n}" "raw": "{\r\n \"quantity\": 1\r\n}"
}, },
"url": { "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": [ "host": [
"{{baseUrl}}" "{{reverseProxy}}"
], ],
"path": [ "path": [
"", "api",
"ShopCartItem", "ShopCartItem",
"{{siteId}}", "{{siteId}}",
"fdc5aa50-ee68-4bae-a8e6-b8ae2c258f60", "fdc5aa50-ee68-4bae-a8e6-b8ae2c258f60",
@ -696,11 +709,12 @@
"raw": "{\r\n \"quantity\": 5\r\n}" "raw": "{\r\n \"quantity\": 5\r\n}"
}, },
"url": { "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": [ "host": [
"{{baseUrl}}" "{{reverseProxy}}"
], ],
"path": [ "path": [
"api",
"ShopCartItem", "ShopCartItem",
"{{siteId}}", "{{siteId}}",
"fdc5aa50-ee68-4bae-a8e6-b8ae2c258f60", "fdc5aa50-ee68-4bae-a8e6-b8ae2c258f60",
@ -727,11 +741,12 @@
} }
], ],
"url": { "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": [ "host": [
"{{baseUrl}}" "{{reverseProxy}}"
], ],
"path": [ "path": [
"api",
"ShopCartItem", "ShopCartItem",
"{{siteId}}", "{{siteId}}",
"fdc5aa50-ee68-4bae-a8e6-b8ae2c258f60", "fdc5aa50-ee68-4bae-a8e6-b8ae2c258f60",
@ -763,11 +778,12 @@
} }
], ],
"url": { "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": [ "host": [
"{{baseUrl}}" "{{reverseProxy}}"
], ],
"path": [ "path": [
"api",
"ShopCartItems", "ShopCartItems",
"{{siteId}}", "{{siteId}}",
"fdc5aa50-ee68-4bae-a8e6-b8ae2c258f60" "fdc5aa50-ee68-4bae-a8e6-b8ae2c258f60"
@ -799,11 +815,12 @@
} }
], ],
"url": { "url": {
"raw": "{{baseUrl}}/ShopCartItems/{{siteId}}/fdc5aa50-ee68-4bae-a8e6-b8ae2c258f60", "raw": "{{reverseProxy}}/api/ShopCartItems/{{siteId}}/fdc5aa50-ee68-4bae-a8e6-b8ae2c258f60",
"host": [ "host": [
"{{baseUrl}}" "{{reverseProxy}}"
], ],
"path": [ "path": [
"api",
"ShopCartItems", "ShopCartItems",
"{{siteId}}", "{{siteId}}",
"fdc5aa50-ee68-4bae-a8e6-b8ae2c258f60" "fdc5aa50-ee68-4bae-a8e6-b8ae2c258f60"
@ -834,11 +851,12 @@
} }
], ],
"url": { "url": {
"raw": "{{baseUrl}}/BlogItem/{{siteId}}/11f2f5f8-1270-4640-b082-c2e7ea8e60b4", "raw": "{{reverseProxy}}/api/BlogItem/{{siteId}}/11f2f5f8-1270-4640-b082-c2e7ea8e60b4",
"host": [ "host": [
"{{baseUrl}}" "{{reverseProxy}}"
], ],
"path": [ "path": [
"api",
"BlogItem", "BlogItem",
"{{siteId}}", "{{siteId}}",
"11f2f5f8-1270-4640-b082-c2e7ea8e60b4" "11f2f5f8-1270-4640-b082-c2e7ea8e60b4"
@ -864,11 +882,12 @@
} }
], ],
"url": { "url": {
"raw": "{{baseUrl}}/BlogItem/{{siteId}}?slug=privacy-terms-and-conditions", "raw": "{{reverseProxy}}/api/BlogItem/{{siteId}}?slug=privacy-terms-and-conditions",
"host": [ "host": [
"{{baseUrl}}" "{{reverseProxy}}"
], ],
"path": [ "path": [
"api",
"BlogItem", "BlogItem",
"{{siteId}}" "{{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}" "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": { "url": {
"raw": "{{baseUrl}}/BlogItem/{{siteId}}", "raw": "{{reverseProxy}}/api/BlogItem/{{siteId}}",
"host": [ "host": [
"{{baseUrl}}" "{{reverseProxy}}"
], ],
"path": [ "path": [
"api",
"BlogItem", "BlogItem",
"{{siteId}}" "{{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}" "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": { "url": {
"raw": "{{baseUrl}}/BlogItem/{{siteId}}/94feda90-ddf6-4717-8879-9c7139e7ff30", "raw": "{{reverseProxy}}/api/BlogItem/{{siteId}}/94feda90-ddf6-4717-8879-9c7139e7ff30",
"host": [ "host": [
"{{baseUrl}}" "{{reverseProxy}}"
], ],
"path": [ "path": [
"api",
"BlogItem", "BlogItem",
"{{siteId}}", "{{siteId}}",
"94feda90-ddf6-4717-8879-9c7139e7ff30" "94feda90-ddf6-4717-8879-9c7139e7ff30"
@ -966,11 +987,12 @@
} }
], ],
"url": { "url": {
"raw": "{{baseUrl}}/BlogItem/{{siteId}}/94feda90-ddf6-4717-8879-9c7139e7ff30", "raw": "{{reverseProxy}}/api/BlogItem/{{siteId}}/94feda90-ddf6-4717-8879-9c7139e7ff30",
"host": [ "host": [
"{{baseUrl}}" "{{reverseProxy}}"
], ],
"path": [ "path": [
"api",
"BlogItem", "BlogItem",
"{{siteId}}", "{{siteId}}",
"94feda90-ddf6-4717-8879-9c7139e7ff30" "94feda90-ddf6-4717-8879-9c7139e7ff30"
@ -1001,11 +1023,12 @@
} }
], ],
"url": { "url": {
"raw": "{{baseUrl}}/BlogItems/{{siteId}}?currentPage=2&itemsPerPage=2", "raw": "{{reverseProxy}}/api/BlogItems/{{siteId}}?currentPage=2&itemsPerPage=2",
"host": [ "host": [
"{{baseUrl}}" "{{reverseProxy}}"
], ],
"path": [ "path": [
"api",
"BlogItems", "BlogItems",
"{{siteId}}" "{{siteId}}"
], ],
@ -1040,11 +1063,12 @@
} }
], ],
"url": { "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": [ "host": [
"{{baseUrl}}" "{{reverseProxy}}"
], ],
"path": [ "path": [
"api",
"BlogItems", "BlogItems",
"{{siteId}}" "{{siteId}}"
], ],
@ -1083,11 +1107,12 @@
} }
], ],
"url": { "url": {
"raw": "{{baseUrl}}/BlogItems/{{siteId}}", "raw": "{{reverseProxy}}/api/BlogItems/{{siteId}}",
"host": [ "host": [
"{{baseUrl}}" "{{reverseProxy}}"
], ],
"path": [ "path": [
"api",
"BlogItems", "BlogItems",
"{{siteId}}" "{{siteId}}"
] ]
@ -1117,15 +1142,16 @@
} }
], ],
"url": { "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": [ "host": [
"{{baseUrl}}" "{{reverseProxy}}"
], ],
"path": [ "path": [
"api",
"File", "File",
"{{siteId}}", "{{siteId}}",
"fdc5aa50-ee68-4bae-a8e6-b8ae2c258f60", "fdc5aa50-ee68-4bae-a8e6-b8ae2c258f60",
"4f163ea9-1786-4192-8efa-3b8ea9ca88fa" "55ecc564-c086-4e77-a8b2-ef32c2a8c280"
] ]
} }
}, },
@ -1158,11 +1184,12 @@
] ]
}, },
"url": { "url": {
"raw": "{{baseUrl}}/File/{{siteId}}/fdc5aa50-ee68-4bae-a8e6-b8ae2c258f60", "raw": "{{reverseProxy}}/api/File/{{siteId}}/fdc5aa50-ee68-4bae-a8e6-b8ae2c258f60",
"host": [ "host": [
"{{baseUrl}}" "{{reverseProxy}}"
], ],
"path": [ "path": [
"api",
"File", "File",
"{{siteId}}", "{{siteId}}",
"fdc5aa50-ee68-4bae-a8e6-b8ae2c258f60" "fdc5aa50-ee68-4bae-a8e6-b8ae2c258f60"
@ -1188,11 +1215,12 @@
} }
], ],
"url": { "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": [ "host": [
"{{baseUrl}}" "{{reverseProxy}}"
], ],
"path": [ "path": [
"api",
"File", "File",
"{{siteId}}", "{{siteId}}",
"fdc5aa50-ee68-4bae-a8e6-b8ae2c258f60", "fdc5aa50-ee68-4bae-a8e6-b8ae2c258f60",
@ -1235,11 +1263,12 @@
] ]
}, },
"url": { "url": {
"raw": "{{baseUrl}}/Files/{{siteId}}/fdc5aa50-ee68-4bae-a8e6-b8ae2c258f60", "raw": "{{reverseProxy}}/api/Files/{{siteId}}/fdc5aa50-ee68-4bae-a8e6-b8ae2c258f60",
"host": [ "host": [
"{{baseUrl}}" "{{reverseProxy}}"
], ],
"path": [ "path": [
"api",
"Files", "Files",
"{{siteId}}", "{{siteId}}",
"fdc5aa50-ee68-4bae-a8e6-b8ae2c258f60" "fdc5aa50-ee68-4bae-a8e6-b8ae2c258f60"
@ -1276,11 +1305,12 @@
] ]
}, },
"url": { "url": {
"raw": "{{baseUrl}}/Files/{{siteId}}/fdc5aa50-ee68-4bae-a8e6-b8ae2c258f60", "raw": "{{reverseProxy}}/api/Files/{{siteId}}/fdc5aa50-ee68-4bae-a8e6-b8ae2c258f60",
"host": [ "host": [
"{{baseUrl}}" "{{reverseProxy}}"
], ],
"path": [ "path": [
"api",
"Files", "Files",
"{{siteId}}", "{{siteId}}",
"fdc5aa50-ee68-4bae-a8e6-b8ae2c258f60" "fdc5aa50-ee68-4bae-a8e6-b8ae2c258f60"
@ -1300,11 +1330,12 @@
"method": "GET", "method": "GET",
"header": [], "header": [],
"url": { "url": {
"raw": "{{baseUrl}}/Image/{{siteId}}/450x300/55ecc564-c086-4e77-a8b2-ef32c2a8c280", "raw": "{{reverseProxy}}/api/Image/{{siteId}}/450x300/55ecc564-c086-4e77-a8b2-ef32c2a8c280",
"host": [ "host": [
"{{baseUrl}}" "{{reverseProxy}}"
], ],
"path": [ "path": [
"api",
"Image", "Image",
"{{siteId}}", "{{siteId}}",
"450x300", "450x300",
@ -1313,17 +1344,148 @@
} }
}, },
"response": [] "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": [ "event": [
{ {
"listen": "prerequest", "listen": "prerequest",
"script": { "script": {
"type": "text/javascript", "type": "text/javascript",
"exec": [ "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": [ "variable": [
{ {
"key": "baseUrl", "key": "reverseProxy",
"value": "https://localhost:7151/api", "value": "https://localhost:7174",
"type": "default" "type": "default"
}, },
{ {
"key": "siteId", "key": "siteId",
"value": "404c8232-9048-4519-bfba-6e78dc7005ca", "value": "404c8232-9048-4519-bfba-6e78dc7005ca",
"type": "default" "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 { namespace Core.Abstractions.DomainObjects {
public abstract class PersonBase<T> : DomainObjectBase<T> { public abstract class PersonBase<T> : DomainObjectBase<T> {
public Guid Id { get; set; } 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; using System.Diagnostics.CodeAnalysis;
namespace Core.Abstractions.Models { 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 class RequestModelBase<T> : ModelBase, IValidatableObject {
public abstract T ToDomainObject(); public abstract T ToDomainObject();
public abstract IEnumerable<ValidationResult> Validate(ValidationContext validationContext); 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> <Nullable>enable</Nullable>
</PropertyGroup> </PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="6.0.2" />
</ItemGroup>
</Project> </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 string Src { get; set; }
public MediaTypes MediaType { get; set; }
public List<MediaAttachmentL10n> L10n { get; set; } public string Alt { get; set; }
public override int GetHashCode() { public override int GetHashCode() {
int hash = 17; int hash = 17;
hash = hash * 23 + Src.GetHashCode(); hash = hash * 23 + Src.GetHashCode();
hash = hash * 23 + L10n.GetHashCode(); hash = hash * 23 + Alt.GetHashCode();
return hash; 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 { namespace Core.DomainObjects.PageSections {
public class TitleSection : PageSectionBase<TitleSection> { public class TitleSection : PageSectionBase<TitleSection> {
public MediaAttachment? Image { get; set; } public Image? Image { get; set; }
public Link? PrimaryLink { get; set; } public Link? PrimaryLink { get; set; }
public Link? SecondaryLink { get; set; } public Link? SecondaryLink { get; set; }
public string? PostedOnBy { 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<IShopCartDataProvider, ShopCartDataProvider>();
services.AddSingleton<ICategoryDataProvider, CategoryDataProvider>(); services.AddSingleton<ICategoryDataProvider, CategoryDataProvider>();
services.AddSingleton<IBlogCatalogDataProvider, BlogCatalogDataProvider>(); services.AddSingleton<IBlogCatalogDataProvider, BlogCatalogDataProvider>();
services.AddSingleton<IUserDataProvider, UserDataProvider>();
#endregion #endregion
#region Buckets #region Buckets

View File

@ -12,7 +12,22 @@
"route1": { "route1": {
"ClusterId": "cluster1", "ClusterId": "cluster1",
"Match": { "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": { "cluster1": {
"Destinations": { "Destinations": {
"destination1": { "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 System.Security.Cryptography;
using Microsoft.AspNetCore.Cryptography.KeyDerivation; using Microsoft.AspNetCore.Cryptography.KeyDerivation;
namespace Services { namespace HashService {
public interface IHashService { public interface IHashService {
(string, string) CreateSaltedHash(string value); (string, string) CreateSaltedHash(string value);
@ -35,6 +35,7 @@ namespace Services {
return (salt, hash); 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> <PropertyGroup>
<TargetFramework>net6.0</TargetFramework> <TargetFramework>net6.0</TargetFramework>
@ -7,7 +7,12 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Cryptography.KeyDerivation" Version="6.0.5" /> <PackageReference Include="DomainResult.Common" Version="3.0.0" />
</ItemGroup> <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> </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.IdentityModel.Tokens.Jwt;
using System.Security.Claims; using System.Security.Claims;
using Microsoft.Extensions.Logging;
using Microsoft.IdentityModel.Tokens; using Microsoft.IdentityModel.Tokens;
namespace Services { namespace JWTService {
public interface IJwtService { public interface IJWTService {
string CreateJwtToken(IEnumerable<string> issuer, DateTime expires, string userId, string userEmail, string userName, IEnumerable<string> userRoles); string CreateJwtToken();
JwtSecurityToken ReadJwtToken(string token); JwtSecurityToken ReadJwtToken(string token);
} }
public class JwtService : IJwtService { public class JWTService : IJWTService {
private readonly JwtSecurityTokenHandler _tokenHandler;
private readonly IJwtServiceSettings _serviceSettings;
public JwtService(IJwtServiceSettings serviceSettings) { private readonly ILogger<JWTService> _logger;
_serviceSettings = serviceSettings;
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(); _tokenHandler = new JwtSecurityTokenHandler();
} }
public string CreateJwtToken(IEnumerable<string> issuer, DateTime expires, string userId, string userEmail, string userName, IEnumerable<string> userRoles) { public string? CreateJwtToken() {
var key = Convert.FromBase64String(_serviceSettings.Secret); 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 // add roles to claims identity from database
var claims = new List<Claim>() { 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 { var token = _tokenHandler.CreateToken(new SecurityTokenDescriptor {
IssuedAt = DateTime.UtcNow, IssuedAt = DateTime.UtcNow,
Subject = new ClaimsIdentity(claims), Subject = new ClaimsIdentity(claims),
Expires = expires, Expires = DateTime.UtcNow.AddDays(_serviceConfig.Expires.Value),
SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha512Signature), SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha512Signature),
}); });
return _tokenHandler.WriteToken(token); 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); 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> <PropertyGroup>
<TargetFramework>net6.0</TargetFramework> <TargetFramework>net6.0</TargetFramework>
@ -7,6 +7,9 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <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" /> <PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="6.18.0" />
</ItemGroup> </ItemGroup>

View File

@ -1,20 +1,22 @@
using DataProviders; using DataProviders;
using JWTService;
namespace WeatherForecast { namespace WeatherForecast {
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public class Configuration : IDataProvidersConfig{ public class Configuration : IDataProvidersConfig, IJWTServiceConfig {
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public string? Secret { get; set; } public JwtConfig? JwtConfig { get; set; }
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public Database? Database { get; set; } 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>
/// ///
/// </summary> /// </summary>
[AllowAnonymous] [Authorize]
[ApiController] [ApiController]
[Route("api/[controller]")] [Route("api/[controller]")]
public class BlogItemController : ControllerBase { public class BlogItemController : ControllerBase {

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -5,52 +5,53 @@ using DomainResults.Mvc;
using WeatherForecast.Services; using WeatherForecast.Services;
namespace WeatherForecast.Controllers; namespace WeatherForecast.Controllers {
/// <summary>
///
/// </summary>
[AllowAnonymous]
[ApiController]
[Route("api/[controller]")]
public class ShopItemsController : ControllerBase {
private readonly IShopItemsService _shopItemsService;
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
/// <param name="shopCatalogService"></param> [Authorize]
public ShopItemsController( [ApiController]
IShopItemsService shopCatalogService [Route("api/[controller]")]
) { public class ShopItemsController : ControllerBase {
_shopItemsService = shopCatalogService;
}
/// <summary> private readonly IShopItemsService _shopItemsService;
///
/// </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>
/// ///
/// </summary> /// </summary>
/// <param name="siteId"></param> /// <param name="shopCatalogService"></param>
/// <returns></returns> public ShopItemsController(
[HttpDelete("{siteId}")] IShopItemsService shopCatalogService
public IActionResult Delete([FromRoute] Guid siteId) { ) {
var result = _shopItemsService.Delete(siteId); _shopItemsService = shopCatalogService;
return result.ToActionResult(); }
/// <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 Microsoft.AspNetCore.Mvc;
using WeatherForecast.Models.Responses; using WeatherForecast.Models.Responses;
@ -7,6 +8,7 @@ namespace WeatherForecast.Controllers;
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
[AllowAnonymous]
[ApiController] [ApiController]
[Route("[controller]")] [Route("[controller]")]
public class WeatherForecastController : ControllerBase { 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;
using Serilog.Enrichers.Span;
namespace WeatherForecast { namespace WeatherForecast {
@ -24,7 +25,8 @@ namespace WeatherForecast {
Host.CreateDefaultBuilder(args) Host.CreateDefaultBuilder(args)
.UseSerilog((hostContext, services, configuration) => { .UseSerilog((hostContext, services, configuration) => {
configuration.ReadFrom.Configuration(hostContext.Configuration) configuration.ReadFrom.Configuration(hostContext.Configuration)
.Enrich.FromLogContext(); .Enrich.FromLogContext()
.Enrich.WithSpan();
}) })
.ConfigureWebHostDefaults(webBuilder => { .ConfigureWebHostDefaults(webBuilder => {
webBuilder.UseStartup<Startup>(); webBuilder.UseStartup<Startup>();

View File

@ -1,4 +1,5 @@
using DataProviders.Collections; using Core.Abstractions;
using DataProviders.Collections;
using DomainResults.Common; using DomainResults.Common;
namespace WeatherForecast.Services.Abstractions { namespace WeatherForecast.Services.Abstractions {
@ -6,7 +7,7 @@ namespace WeatherForecast.Services.Abstractions {
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public abstract class PostItemServiceBase { public abstract class PostItemServiceBase<T> : ServiceBase<T> {
/// <summary> /// <summary>
/// ///
@ -16,10 +17,12 @@ namespace WeatherForecast.Services.Abstractions {
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
/// <param name="logger"></param>
/// <param name="categoryDataProvider"></param> /// <param name="categoryDataProvider"></param>
public PostItemServiceBase( public PostItemServiceBase(
ILogger<T> logger,
ICategoryDataProvider categoryDataProvider ICategoryDataProvider categoryDataProvider
) { ) : base(logger) {
_categoryDataProvider = categoryDataProvider; _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 DomainResults.Common;
using ExtensionMethods;
using DataProviders;
using Core.DomainObjects;
using Core.DomainObjects.Documents;
using Core.DomainObjects.L10n;
using Core.Enumerations; using Core.Enumerations;
using ExtensionMethods;
using DataProviders.Collections;
using WeatherForecast.Models.Requests; using WeatherForecast.Models.Requests;
using WeatherForecast.Models.Responses; using WeatherForecast.Models.Responses;
using DataProviders.Collections;
using WeatherForecast.Services.Abstractions; using WeatherForecast.Services.Abstractions;
namespace WeatherForecast.Services { namespace WeatherForecast.Services {
@ -64,8 +59,8 @@ namespace WeatherForecast.Services {
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public class BlogItemService : PostItemServiceBase, IBlogItemService { public class BlogItemService : PostItemServiceBase<BlogItemService>, IBlogItemService {
private readonly ILogger<BlogItemService> _logger;
private readonly IBlogCatalogDataProvider _blogCatalogDataProvider; private readonly IBlogCatalogDataProvider _blogCatalogDataProvider;
/// <summary> /// <summary>
@ -78,8 +73,7 @@ namespace WeatherForecast.Services {
ILogger<BlogItemService> logger, ILogger<BlogItemService> logger,
IBlogCatalogDataProvider blogCatalogDataProvider, IBlogCatalogDataProvider blogCatalogDataProvider,
ICategoryDataProvider categoryDataProvider ICategoryDataProvider categoryDataProvider
) : base(categoryDataProvider) { ) : base(logger, categoryDataProvider) {
_logger = logger;
_blogCatalogDataProvider = blogCatalogDataProvider; _blogCatalogDataProvider = blogCatalogDataProvider;
} }

View File

@ -1,14 +1,10 @@
using DomainResults.Common; using DomainResults.Common;
using DataProviders;
using Core.Abstractions; using Core.Abstractions;
using Core.DomainObjects;
using Core.Enumerations; using Core.Enumerations;
using DataProviders.Collections;
using WeatherForecast.Models.Responses; using WeatherForecast.Models.Responses;
using DataProviders.Collections;
using Core.DomainObjects.Documents;
namespace WeatherForecast.Services { namespace WeatherForecast.Services {
@ -40,9 +36,8 @@ namespace WeatherForecast.Services {
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public class BlogItemsService : IBlogItemsService { public class BlogItemsService : ServiceBase<BlogItemsService>, IBlogItemsService {
private readonly ILogger<BlogItemsService> _logger;
private readonly IBlogCatalogDataProvider _blogCatalogDataProvider; private readonly IBlogCatalogDataProvider _blogCatalogDataProvider;
private readonly ICategoryDataProvider _categoryDataProvider; private readonly ICategoryDataProvider _categoryDataProvider;
@ -56,8 +51,7 @@ namespace WeatherForecast.Services {
ILogger<BlogItemsService> logger, ILogger<BlogItemsService> logger,
IBlogCatalogDataProvider blogCatalogDataProvider, IBlogCatalogDataProvider blogCatalogDataProvider,
ICategoryDataProvider categoryDataProvider ICategoryDataProvider categoryDataProvider
) { ) : base(logger) {
_logger = logger;
_blogCatalogDataProvider = blogCatalogDataProvider; _blogCatalogDataProvider = blogCatalogDataProvider;
_categoryDataProvider = categoryDataProvider; _categoryDataProvider = categoryDataProvider;
} }

View File

@ -1,12 +1,12 @@
using DomainResults.Common; using DomainResults.Common;
using DataProviders; using DataProviders.Collections;
using Core.Enumerations; using Core.Enumerations;
using WeatherForecast.Models.Requests; using WeatherForecast.Models.Requests;
using WeatherForecast.Models.Responses; using WeatherForecast.Models.Responses;
using DataProviders.Collections; using Core.Abstractions;
namespace WeatherForecast.Services { namespace WeatherForecast.Services {
@ -60,9 +60,8 @@ namespace WeatherForecast.Services {
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public class CategoryItemService : ICategoryItemService { public class CategoryItemService : ServiceBase<CategoryItemService>, ICategoryItemService {
private readonly ILogger<CategoryItemService> _logger;
private readonly ICategoryDataProvider _categoryDataProvider; private readonly ICategoryDataProvider _categoryDataProvider;
/// <summary> /// <summary>
@ -73,8 +72,7 @@ namespace WeatherForecast.Services {
public CategoryItemService( public CategoryItemService(
ILogger<CategoryItemService> logger, ILogger<CategoryItemService> logger,
ICategoryDataProvider categoryDataProvider ICategoryDataProvider categoryDataProvider
) { ) : base(logger) {
_logger = logger;
_categoryDataProvider = categoryDataProvider; _categoryDataProvider = categoryDataProvider;
} }

View File

@ -1,12 +1,12 @@
using DomainResults.Common; using DomainResults.Common;
using DataProviders; using DataProviders.Collections;
using Core.Abstractions; using Core.Abstractions;
using Core.Enumerations; using Core.Enumerations;
using WeatherForecast.Models.Responses; using WeatherForecast.Models.Responses;
using DataProviders.Collections;
namespace WeatherForecast.Services { namespace WeatherForecast.Services {
@ -34,9 +34,8 @@ namespace WeatherForecast.Services {
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public class CategoryItemsService : ICategoryItemsService { public class CategoryItemsService : ServiceBase<CategoryItemsService>, ICategoryItemsService {
private readonly ILogger<CategoryItemsService> _logger;
private readonly ICategoryDataProvider _categoryDataProvider; private readonly ICategoryDataProvider _categoryDataProvider;
/// <summary> /// <summary>
@ -47,8 +46,7 @@ namespace WeatherForecast.Services {
public CategoryItemsService( public CategoryItemsService(
ILogger<CategoryItemsService> logger, ILogger<CategoryItemsService> logger,
ICategoryDataProvider categoryDataProvider ICategoryDataProvider categoryDataProvider
) { ) : base(logger) {
_logger = logger;
_categoryDataProvider = categoryDataProvider; _categoryDataProvider = categoryDataProvider;
} }

View File

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

View File

@ -1,6 +1,8 @@
using DataProviders; using DomainResults.Common;
using DataProviders;
using DataProviders.Buckets; using DataProviders.Buckets;
using DomainResults.Common; using Core.Abstractions;
namespace WeatherForecast.Services { namespace WeatherForecast.Services {
@ -40,9 +42,8 @@ namespace WeatherForecast.Services {
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public class FileService : IFileService { public class FileService : ServiceBase<FileService>, IFileService {
private readonly ILogger<FilesService> _logger;
private readonly IFilesService _filesService; private readonly IFilesService _filesService;
private readonly IImageBucketDataProvider _imageBucketDataProvider; private readonly IImageBucketDataProvider _imageBucketDataProvider;
@ -53,11 +54,10 @@ namespace WeatherForecast.Services {
/// <param name="filesService"></param> /// <param name="filesService"></param>
/// <param name="imageBucketDataProvider"></param> /// <param name="imageBucketDataProvider"></param>
public FileService( public FileService(
ILogger<FilesService> logger, ILogger<FileService> logger,
IFilesService filesService, IFilesService filesService,
IImageBucketDataProvider imageBucketDataProvider IImageBucketDataProvider imageBucketDataProvider
) { ) : base(logger) {
_logger = logger;
_filesService = filesService; _filesService = filesService;
_imageBucketDataProvider = imageBucketDataProvider; _imageBucketDataProvider = imageBucketDataProvider;
} }

View File

@ -1,7 +1,10 @@
using DataProviders; using DomainResults.Common;
using DataProviders;
using DataProviders.Buckets; using DataProviders.Buckets;
using DomainResults.Common;
using FileSecurityService; using FileSecurityService;
using Core.Abstractions;
namespace WeatherForecast.Services { namespace WeatherForecast.Services {
@ -31,9 +34,8 @@ namespace WeatherForecast.Services {
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public class FilesService : IFilesService { public class FilesService : ServiceBase<FilesService>, IFilesService {
private readonly ILogger<FilesService> _logger;
private readonly IFileSecurityService _fileSecurityService; private readonly IFileSecurityService _fileSecurityService;
private readonly IImageBucketDataProvider _imageBucketDataProvider; private readonly IImageBucketDataProvider _imageBucketDataProvider;
@ -46,8 +48,7 @@ namespace WeatherForecast.Services {
ILogger<FilesService> logger, ILogger<FilesService> logger,
IFileSecurityService fileSecurityService, IFileSecurityService fileSecurityService,
IImageBucketDataProvider imageBucketDataProvider IImageBucketDataProvider imageBucketDataProvider
) { ) : base(logger) {
_logger = logger;
_fileSecurityService = fileSecurityService; _fileSecurityService = fileSecurityService;
_imageBucketDataProvider = imageBucketDataProvider; _imageBucketDataProvider = imageBucketDataProvider;
} }

View File

@ -1,10 +1,12 @@
 using DomainResults.Common;
using DataProviders; using DataProviders;
using DataProviders.Buckets; using DataProviders.Buckets;
using DataProviders.Collections; using DataProviders.Collections;
using DomainResults.Common;
using ImageProvider; using ImageProvider;
using ImageProvider.Fonts; using ImageProvider.Fonts;
using Core.Abstractions;
namespace WeatherForecast.Services { namespace WeatherForecast.Services {
@ -26,9 +28,8 @@ namespace WeatherForecast.Services {
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public class ImageService : IImageService { public class ImageService : ServiceBase<ImageService>, IImageService {
private readonly ILogger<ImageService> _logger;
private readonly IImageBucketDataProvider _imageBucketDataProvider; private readonly IImageBucketDataProvider _imageBucketDataProvider;
private readonly IImageProvider _imageProvider; private readonly IImageProvider _imageProvider;
private readonly IContentDataProvider _contentDataProvider; private readonly IContentDataProvider _contentDataProvider;
@ -44,9 +45,7 @@ namespace WeatherForecast.Services {
IImageBucketDataProvider imageBucketDataProvider, IImageBucketDataProvider imageBucketDataProvider,
IImageProvider imageProvider, IImageProvider imageProvider,
IContentDataProvider contentDataProvider IContentDataProvider contentDataProvider
) : base(logger) {
) {
_logger = logger;
_imageBucketDataProvider = imageBucketDataProvider; _imageBucketDataProvider = imageBucketDataProvider;
_imageProvider = imageProvider; _imageProvider = imageProvider;
_contentDataProvider = contentDataProvider; _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>
/// ///
/// </summary> /// </summary>
public class ShopCartItemService : IShopCartItemService { public class ShopCartItemService : ServiceBase<ShopCartItemService>, IShopCartItemService {
private readonly ILogger<ShopCartItemService> _logger;
private readonly IShopCatalogDataProvider _shopCatalogDataProvider; private readonly IShopCatalogDataProvider _shopCatalogDataProvider;
private readonly IShopCartDataProvider _shopCartDataProvider; private readonly IShopCartDataProvider _shopCartDataProvider;
@ -74,8 +73,7 @@ namespace WeatherForecast.Services {
ILogger<ShopCartItemService> logger, ILogger<ShopCartItemService> logger,
IShopCatalogDataProvider shopCatalogDataProvider, IShopCatalogDataProvider shopCatalogDataProvider,
IShopCartDataProvider shopCartDataprovider IShopCartDataProvider shopCartDataprovider
) { ) : base(logger) {
_logger = logger;
_shopCatalogDataProvider = shopCatalogDataProvider; _shopCatalogDataProvider = shopCatalogDataProvider;
_shopCartDataProvider = shopCartDataprovider; _shopCartDataProvider = shopCartDataprovider;
} }

View File

@ -1,12 +1,11 @@
using DomainResults.Common; using DomainResults.Common;
using DataProviders; using DataProviders.Collections;
using Core.Enumerations; using Core.Enumerations;
using Core.Abstractions; using Core.Abstractions;
using WeatherForecast.Models.Responses; using WeatherForecast.Models.Responses;
using DataProviders.Collections;
namespace WeatherForecast.Services { namespace WeatherForecast.Services {
@ -36,9 +35,8 @@ namespace WeatherForecast.Services {
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public class ShopCartItemsService : IShopCartItemsService { public class ShopCartItemsService : ServiceBase<ShopCartItemsService>, IShopCartItemsService {
private readonly ILogger<ShopCartItemsService> _logger;
private readonly IShopCatalogDataProvider _shopCatalogDataProvider; private readonly IShopCatalogDataProvider _shopCatalogDataProvider;
private readonly IShopCartDataProvider _shopCartDataProvider; private readonly IShopCartDataProvider _shopCartDataProvider;
@ -52,8 +50,7 @@ namespace WeatherForecast.Services {
ILogger<ShopCartItemsService> logger, ILogger<ShopCartItemsService> logger,
IShopCatalogDataProvider shopCatalogDataProvider, IShopCatalogDataProvider shopCatalogDataProvider,
IShopCartDataProvider shopCartDataprovider IShopCartDataProvider shopCartDataprovider
) { ) : base(logger) {
_logger = logger;
_shopCatalogDataProvider = shopCatalogDataProvider; _shopCatalogDataProvider = shopCatalogDataProvider;
_shopCartDataProvider = shopCartDataprovider; _shopCartDataProvider = shopCartDataprovider;
} }

View File

@ -1,13 +1,13 @@
using DomainResults.Common; using DomainResults.Common;
using DataProviders.Collections;
using ExtensionMethods; using ExtensionMethods;
using Core.Enumerations; using Core.Enumerations;
using WeatherForecast.Models; using WeatherForecast.Models;
using WeatherForecast.Models.Requests; using WeatherForecast.Models.Requests;
using DataProviders.Collections;
using Core.DomainObjects.Documents;
using WeatherForecast.Services.Abstractions; using WeatherForecast.Services.Abstractions;
namespace WeatherForecast.Services { namespace WeatherForecast.Services {
@ -63,9 +63,8 @@ namespace WeatherForecast.Services {
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public class ShopItemService : PostItemServiceBase, IShopItemService { public class ShopItemService : PostItemServiceBase<ShopItemService>, IShopItemService {
private readonly ILogger<ShopItemService> _logger;
private readonly IShopCatalogDataProvider _shopCatalogDataProvider; private readonly IShopCatalogDataProvider _shopCatalogDataProvider;
/// <summary> /// <summary>
@ -78,8 +77,7 @@ namespace WeatherForecast.Services {
ILogger<ShopItemService> logger, ILogger<ShopItemService> logger,
IShopCatalogDataProvider shopCatalogDataProvider, IShopCatalogDataProvider shopCatalogDataProvider,
ICategoryDataProvider categoryDataProvider ICategoryDataProvider categoryDataProvider
) : base(categoryDataProvider) { ) : base(logger, categoryDataProvider) {
_logger = logger;
_shopCatalogDataProvider = shopCatalogDataProvider; _shopCatalogDataProvider = shopCatalogDataProvider;
} }

View File

@ -1,15 +1,12 @@
using DomainResults.Common; using DomainResults.Common;
using DataProviders; using DataProviders.Collections;
using Core.Abstractions; using Core.Abstractions;
using Core.DomainObjects;
using Core.Enumerations; using Core.Enumerations;
using WeatherForecast.Models; using WeatherForecast.Models;
using WeatherForecast.Models.Responses; using WeatherForecast.Models.Responses;
using DataProviders.Collections;
using Core.DomainObjects.Documents;
namespace WeatherForecast.Services { namespace WeatherForecast.Services {
@ -41,8 +38,8 @@ namespace WeatherForecast.Services {
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public class ShopItemsService : IShopItemsService { public class ShopItemsService : ServiceBase<ShopItemsService>, IShopItemsService {
private readonly ILogger<ShopItemsService> _logger;
private readonly IShopCatalogDataProvider _shopCatalogDataProvider; private readonly IShopCatalogDataProvider _shopCatalogDataProvider;
private readonly ICategoryDataProvider _categoryDataProvider; private readonly ICategoryDataProvider _categoryDataProvider;
@ -56,8 +53,7 @@ namespace WeatherForecast.Services {
ILogger<ShopItemsService> logger, ILogger<ShopItemsService> logger,
IShopCatalogDataProvider shopCatalogDataprovider, IShopCatalogDataProvider shopCatalogDataprovider,
ICategoryDataProvider categoryDataProvider ICategoryDataProvider categoryDataProvider
) { ) : base(logger) {
_logger = logger;
_shopCatalogDataProvider = shopCatalogDataprovider; _shopCatalogDataProvider = shopCatalogDataprovider;
_categoryDataProvider = categoryDataProvider; _categoryDataProvider = categoryDataProvider;
} }

View File

@ -8,6 +8,8 @@ using DataProviders.Extensions;
using System.Text.Json.Serialization; using System.Text.Json.Serialization;
using FileSecurityService.Extensions; using FileSecurityService.Extensions;
using ImageProvider.Extensions; using ImageProvider.Extensions;
using JWTService.Extensions;
using HashService.Extensions;
namespace WeatherForecast { namespace WeatherForecast {
@ -52,7 +54,7 @@ namespace WeatherForecast {
options.JsonSerializerOptions.DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull); options.JsonSerializerOptions.DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull);
#region configure jwt authentication #region configure jwt authentication
if (appSettings.Secret != null) { if (appSettings.JwtConfig?.Secret != null) {
services.AddAuthentication(options => { services.AddAuthentication(options => {
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
@ -61,7 +63,7 @@ namespace WeatherForecast {
options.SaveToken = true; options.SaveToken = true;
options.TokenValidationParameters = new TokenValidationParameters { options.TokenValidationParameters = new TokenValidationParameters {
ValidateIssuerSigningKey = true, ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(Convert.FromBase64String(appSettings.Secret)), IssuerSigningKey = new SymmetricSecurityKey(Convert.FromBase64String(appSettings.JwtConfig.Secret)),
ValidateIssuer = false, ValidateIssuer = false,
ValidateAudience = false ValidateAudience = false
}; };
@ -85,10 +87,14 @@ namespace WeatherForecast {
services.AddScoped<IFileService, FileService>(); services.AddScoped<IFileService, FileService>();
services.AddScoped<IFilesService, FilesService>(); services.AddScoped<IFilesService, FilesService>();
services.AddScoped<IImageService, ImageService>(); services.AddScoped<IImageService, ImageService>();
services.AddScoped<IPasswordService, PasswordService>();
services.AddScoped<IAuthenticationService, AutheticationService>();
services.RegisterDataproviders(appSettings); services.RegisterDataproviders(appSettings);
services.RegisterFileSecurityService(); services.RegisterFileSecurityService();
services.RegisterImageProvider(); services.RegisterImageProvider();
services.RegisterJWTService(appSettings);
services.RegisterHashService();
#region Swagger #region Swagger
services.ConfigureSwaggerGen(options => { services.ConfigureSwaggerGen(options => {

View File

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

View File

@ -8,14 +8,18 @@
"Name": "Console", "Name": "Console",
"Args": { "Args": {
"restrictedToMinimumLevel": "Information", "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": "*", "AllowedHosts": "*",
"Configuration": { "Configuration": {
"Secret": "TUlJQ1d3SUJBQUtCZ0djczU2dnIzTWRwa0VYczYvYjIyemxMWlhSaFdrSWtyN0dqUHB4ZkNpQk9FU2Q3L2VxcA==", "JwtConfig": {
"Secret": "TUlJQ1d3SUJBQUtCZ0djczU2dnIzTWRwa0VYczYvYjIyemxMWlhSaFdrSWtyN0dqUHB4ZkNpQk9FU2Q3L2VxcA==",
"Expires": "365"
},
"Database": { "Database": {
"ConnectionString": "mongodb://localhost:27017" "ConnectionString": "mongodb://localhost:27017"