diff --git a/source/documentation/LICENSE.txt b/source/documentation/LICENSE.txt new file mode 100644 index 00000000..c1684bed --- /dev/null +++ b/source/documentation/LICENSE.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2015-2019 Capgemini SE. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/source/documentation/_Footer.md b/source/documentation/_Footer.md new file mode 100644 index 00000000..b3e25d46 --- /dev/null +++ b/source/documentation/_Footer.md @@ -0,0 +1 @@ +Creative Commons License Agreement
This documentation is licensed under the Creative Commons License (Attribution-NoDerivatives 4.0 International). \ No newline at end of file diff --git a/source/documentation/_sidebar.asciidoc b/source/documentation/_sidebar.asciidoc new file mode 100644 index 00000000..e69de29b diff --git a/source/documentation/architecture_guide.asciidoc b/source/documentation/architecture_guide.asciidoc new file mode 100644 index 00000000..dd09cb21 --- /dev/null +++ b/source/documentation/architecture_guide.asciidoc @@ -0,0 +1,91 @@ +:toc: + +[.text-justify] + += Architecture + +toc::[] + +== Introduction + +The https://devonfw.com/website/pages/welcome/welcome.html[devonfw] platform provides a solution to building applications which combine best-in-class frameworks and libraries as well as industry proven practices and code conventions. It massively speeds up development, reduces risks and helps you to deliver better results. When it comes to achieving these objectives, having a very clear and well-defined architecture is critical. + +//Comentar lo que se va a explicar en el documento +This guide will teach you the fundamentals of the suggested architecture, which is based on layers in order to develop the best possible quality software, applying design patterns, coding principles and the best practices known in the industry. + +Before getting started, it's helpful to understand a few key ideas that will come in handy. + +//Conceptos previos +=== What is code quality? +Quality is a subjective concept; one person may regard something as high quality while another does not. So, how can we tell whether a piece of code is of good quaility or not? +Different teams may use different definitions, based on context, but there are five common standard metrics used to measure it: + +* *Reliability:* Measures the probability of a system running without failure over a specific period of time. It relates to the number of defects and availability of the software. +* *Maintainability:* Measures how easily software can be maintained. It relates to the size, consistency, structure, and complexity of the codebase. +* *Testability:* Measures how well the software supports testing efforts. It relies on how well you can control, observe, isolate, and automate testing, among other factors. +* *Portability:* Measures how usable the same software is in different environments. +* *Reusability:* Measures whether existing assets, such as code, can be used again. Assets are more easily reused if they have characteristics such as modularity or loose coupling. + +=== What is architecture quality? +Using a well-defined architecture is essential to ensure quality development of long-lived business applications as well as applications with complex behavior. + +* *Scalability:* Software scalability is the ability to grow or shrink a piece of software to meet changing demands on a business. +* *Loose coupling:* Loose coupling is an approach to interconnecting the components in a system or network so that they are weakly associated and easily replaceable. +* *Developer friendly:* A clean, structured and well-documented architecture makes reading and understanding the code much easier to developers. + +== Onion Architecture +As the name suggests, the proposed architecture makes use of cooperating components called layers, just like an onion. + +"It is important to understand the difference between layers and tiers. Layers describe the logical groupings of the functionality and components in an application; whereas tiers describe the physical distribution of the functionality and components on separate servers, computers, networks, or remote locations. Although both layers and tiers use the same set of names (presentation, business, services, and data), remember that only tiers imply a physical separation. It is quite common to locate more than one layer on the same physical machine (the same tier). You can think of the term tier as referring to physical distribution patterns such as two-tier, three-tier, and n-tier." +-- Layered Application Guidelines, MSDN Microsoft + +The main objective is to control the coupling in such way that the high-level modules do not rely on low level ones, but rather on abstractions of them. Components in a loosely coupled system can be replaced with alternative implementations that provide the same services. + +This principle is called https://en.wikipedia.org/wiki/Dependency_inversion_principle[Dependency Injection]. To implement it, we will also be using the https://docs.microsoft.com/en-us/aspnet/core/fundamentals/dependency-injection?view=aspnetcore-6.0[Dependency Injection] pattern available in .NET Core. + +=== Domain Layer +This type of architecture also follows Domain-Driven-Design (DDD) principles, so we can find the Domain Model in the very center. It represents the state and behavior combination that models truth for the organization. + +.Domain Layer diagram +image::images/onion_architecture_domain.png[] + +As shown in the diagram, the entities and the database context that provides access to an external database are placed in the core of the application. Repository contracts (interfaces) that provide object saving and retrieving behavior can also be found in this layer. + +The Domain Model is only coupled to itself, so it doesn't have any dependency on other application layers. + +=== Data Layer +The first layer around the Domain Model is typically the one that orchestrates the data obtained from the database, betweeen the Domain Layer and the Business Layer. + +.Data Layer diagram +image::images/onion_architecture_data.png[] + +To provide an abstraction of the data access methods, the Repository Pattern is being used. In this layer the implementations of the repository interfaces are found. As well as any other necesary implementation such as the Unit of Work. + +=== Business Layer + +The business layer holds all the application logic and core functionality. It may implement each required API controller as well as the services that go along with them. + +Sometimes services or interfaces defined at this layer will need to work with non-entity types. These objects are known as data transfer objects (DTOs) and they are used to decouple the logic from the domain. This enables the data to be optimized and made available to a variety of data users. Thanks to a series of converters, the data can be optimized and be ready for different consumers. + +.Business Layer diagram +image::images/onion_architecture_business.png[] + +=== Application Layer + +The outer layer of our onion encapsulates the different front-end clients and its resource dependencies. Following also Test-Driven-Development (TDD) principles we will find the Tests. + +.Application Layer diagram +image::images/onion_architecture_application.png[] + +As shown in the diagram, this layer may use many external components such as data sources, identity providers and other services. + +== References +Here are some interesting references to continue learning about this topic: + +* https://docs.microsoft.com/en-us/dotnet/architecture/modern-web-apps-azure/common-web-application-architectures[Common web Application Architectures - Microsoft Docs] + +* https://docs.microsoft.com/en-us/dotnet/architecture/modern-web-apps-azure/architectural-principles[Architectural Principles - Microsoft Docs] + +* https://docs.microsoft.com/en-us/aspnet/core/fundamentals/dependency-injection?view=aspnetcore-6.0[Dependency injection in ASP.NET Core - Microsoft Docs] + +* https://docs.microsoft.com/es-es/dotnet/architecture/microservices/microservice-ddd-cqrs-patterns/infrastructure-persistence-layer-design[Design the infrastructure persistence layer - Microsoft Docs] \ No newline at end of file diff --git a/source/documentation/cobiGen.asciidoc b/source/documentation/cobiGen.asciidoc new file mode 100644 index 00000000..c644df0e --- /dev/null +++ b/source/documentation/cobiGen.asciidoc @@ -0,0 +1,134 @@ +:toc: macro +toc::[] +:icons: font +:iconfont-remote!: +:iconfont-name: font-awesome +:stylesdir: css + += devon4net Cobigen Guide + +== Overview + +In this guide we will explain how to generate a new `WebApi` project from an OpenAPI 3.0.0 specification. This means that we are going to use a “contract first” strategy. This is going to be possible due to these type of files that contain all the information about entities, operations, etc… + +In order to make it work we are using https://github.com/devonfw/cobigen[`CobiGen`], a powerful tool for generating source code. `CobiGen` allows users to generate all the structure and code of the components, helping to save a lot of time otherwise wasted on repetitive tasks. + +== Getting things ready + +=== devonfw Distribution + +The devonfw distributions can be obtained from the https://coconet.capgemini.com/sf/frs/do/listReleases/projects.apps2_devon/frs.devon_distribution[`TeamForge` releases library] and are packaged in zips files that include all the needed tools, software and configurations. + +It is not necessary to install nor configure anything. Just extracting the zip content is enough to have a fully functional devonfw. The only thing you have to do is run *create-or-update-workspace.bat* and then *update-all-workspaces.bat* to set up all the needed tools. + +=== devon4net Templates + +We are going to use the template of devon4net as a base to generate all the code, so what we have to do now is to download said template using the following steps. + +First of all you have to set up all the environment for .NET, you can do this using https://devon4net.github.io/environment.html[the following tutorial]. Next we are going to create a new folder where we want to have the WebAPI project, lastly we are going to open the terminal there. + +Type the following: + + dotnet new -i `Devon4Net`.WebAPI.Template + +and then: + + dotnet new Devon4NetAPI + +=== OpenAPI File + +In order to let `CobiGen` generate all the files, we first have to make some modifications to our OpenAPI file. + +It is obligatory to put the _“x-rootpackage”_ tag to indicate where `CobiGen` will place the generated files as well as the _"x-component"_ tags for each component, keep in mind that due to `CobiGen`'s limitations each component *_must_* have its own entity. + +You can read more information about how to configure your OpenAPI file and a working example https://github.com/devonfw/cobigen/wiki/cobigen-openapiplugin#full-example[here]. + +== Generating files + +Cobigen allow us to generate the files in two different ways. One of them is using Eclipse which it can be done by using the its graphical interface. The other way to generate the code is using the Cobigen CLI tool. + +=== Generating files through Eclipse +In order to generate the files using Eclipse we need to follow some simple steps. + +First we are going to import our basic devon4net WebAPI Project into Eclipse. to do so open Eclipse with the “eclipse-main.bat” file that can be found in the devon distribution root folder. Once we are inside of Eclipse we go to *File > Open projects from file system...* and, under "Directory", search for your project. + +[[img-cobigen]] +image::images/Project_selection.png["cobigen", width=="600", link=="images/Project_selection.png"] + +Next we copy our OpenAPI file into the root folder of the project. + +[[img-cobigen]] +image::images/OpenAPI_file_root_folder.png["cobigen", width=="300", link=="images/OpenAPI_file_root_folder.png"] + +And then we right click on OpenAPI file and then select *CobiGen > Generate...* It will display a window like this: + +[[img-cobigen]] +image::images/cobigen_generate0.png["cobigen", width=="800", link=="images/cobigen_generate0.png"] + +To select all .NET features choose *CRUD devon4net Server* otherwise you can select only those that interest you. + +[[img-cobigen]] +image::images/cobigen_generate1.png["cobigen", width=="800", link=="images/cobigen_generate1.png] + +Ones you select all the files that you want to generate, click on the _“Finish”_ button to generate all the source code. + +=== Generating files through Cobigen CLI + +In order to generate the files using the Cobigen CLI it is needed to do the following steps: + +1. Go to devonfw distribution folder +2. Run *console.bat*, this will open a console. +3. Go to the folder you downloaded the *devon4net template* and your *yml* file. +4. Run the command: + + cobigen generate {yourOpenAPIFile}.yml + +5. A list of increments will be printed so that you can start the generation. It has to be selected *CRUD devon4net Server* increment. + +== Configuration + +=== Dependency Injection configuration + +At this point it is needed to make some modifications in the code in order to configure correctly the server. To do so it is needed to locate the services and the repositories files that were created in *Devon4Net.WebAPI.Implementation* + +Services location: +[[img-cobigen]] +image::images/Services.png["cobigen", width=="300", link=="images/Services.png] + +Repositories location: +[[img-cobigen]] +image::images/Repositories.png["cobigen", width=="300", link=="images/Repositories.png] + +Now, we are going to open the following file `*Devon4Net.WebAPI.Implementation\Configure\DevonConfiguration.cs*`. +In there we have to add the Dependency Injection for the services and the repositories that Cobigen has generated. The following image is an example of what is needed to add. + +[[img-cobigen]] +image::images/BussinessConfiguration.png["cobigen", width=="800", link=="images/BussinessConfiguration.png] + +Moreover it is needed to remove the last line in order to be able to run the application: + + `throw new NotImplementedException(...);` + +=== Configure data base + +Cobigen is generating an empty context that has to be filled with manually in order to be able to work with the database. The context can be found in `*[Project_Name]/Devon4Net.WebAPI.Implementation/Domain/Database/CobigenContext.cs*`. + +[[img-cobigen]] +image::images/CobigenContextLocation.png["cobigen", width=="350", link=="images/CobigenContextLocation.png] + +=== Configure services + +In order to finish the configuration of the services it is needed to go to each service file of the managements generated. + +In there we will see some `"NotImplementedExceptions"`, so it is needed to read carefully each comment inside of each exception in order to be able to use the service. It can be shown an example of the service with its `NotImplementedExceptions` comments: + +[[img-cobigen]] +image::images/ServiceExample.png["cobigen", width=="800", link=="images/ServiceExample.png] + +=== Run the application + +After doing all the steps defined above, open a terminal in path: *[Project_Name]/Devon4Net.Application.WebAPI* and then type: + + dotnet run + +This will deploy our application in our localhost with the port 8081, so when you click https://localhost:8082/swagger/index.html[here] (https://localhost:8082/swagger) you can see, in swagger, all the services and the data model. diff --git a/source/documentation/codeconvention.asciidoc b/source/documentation/codeconvention.asciidoc new file mode 100644 index 00000000..c968de90 --- /dev/null +++ b/source/documentation/codeconvention.asciidoc @@ -0,0 +1,268 @@ +:toc: += Code conventions + +toc::[] + +== Introduction +Writing code without conventions and standards can easily become a nightmare for all members of a development team. + +This document covers .NET Coding Standards and is recommended to be read by team leaders, architects and any developing team operating in the Microsoft .NET environment. + +=== What is a coding standard? +Coding standards are collections of rules and guidelines that determine the programming style, procedures and methods for a programming language. + +"All the code in the system looks as if it was written by a single – very competent – individual" +-- K. Beck + +== Terminology +=== Camel Case (`camelCase`) +In camel case each word or abbreviation in the middle of the phrase begins with a capital letter, with no intervening spaces or punctuation. + +The `camelCasing` convention, used only for parameter names, capitalizes the first character of each word except the first word, as shown in the following examples. As the example also shows, two-letter acronyms that begin a camel-cased identifier are both lowercase. + +image:icons/thumbs_up_solid.png[] Use `camelCasing` for inline variables: + +[source, c#] +---- + var finalPrice = 99.99; +---- + +image:icons/thumbs_down_solid.png[] Do not use simple concatenation: +[source, c#] +---- + var finalprice = 99.99; +---- + + +=== Pascal Case (`PascalCase`) +The first letter of each concatenated word is capitalized. No other characters are used to separate the words, like hyphens or underscores. + +The `PascalCasing` convention, used for all identifiers except parameter names, capitalizes the first character of each word (including acronyms over two letters in length). + +image:icons/thumbs_up_solid.png[] Use `PascalCasing` for all public member, type, and names of namespaces consisting of multiple words. + +[source, c#] +---- + public class MyClass + { + } +---- + +image:icons/thumbs_down_solid.png[] Do not use any capital letters + +[source, c#] +---- + public class MYCLASS + { + } +---- + +=== Snake Case (`snake_case`) +Each word is written in lower case and separated by an underscore. Capital letters and other separation methods aren't used. + +The `snake_casing` is used in resources file names, database names and keys. + +image:icons/thumbs_up_solid.png[] Use `snake_casing` in file names: +---- + thumbs_up.png +---- + +image:icons/thumbs_down_solid.png[] Do not use any other symbol than ( _ , - , . ): +---- + thumbs#up.png +---- + + +=== Underscore Prefix (`_underscorePrefix`) +In this type of naming, an underscore is added at the beginning of the word. After it, the name can follow other type of casing, such as camel case + +image:icons/thumbs_up_solid.png[] Use `_underscorePrefix` in private fields: +[source, c#] +---- + public class MyClass + { + private string _myField; + } +---- + +image:icons/thumbs_down_solid.png[] Do not use underscores in public fields: +[source, c#] +---- + public class MyClass + { + public string _myField; + } +---- + +== General Naming Conventions +image:icons/thumbs_up_solid.png[] Choose easily readable identifier names. + +image:icons/thumbs_up_solid.png[] Favor readability over brevity. + + * e.g.: `GetLength` is a better name than `GetInt`. + + * Aim for the “ubiquitous language” (E. Evans): A language distilled from the domain language, which helps the team clarifying domain concepts and communicating with domain experts. + +image:icons/thumbs_up_solid.png[] Prefer adding a suffix rather than a prefix to indicate a new version of an existing `API`. + +image:icons/thumbs_up_solid.png[] Use a numeric suffix to indicate a new version of an existing `API`, particularly if the existing name of the `API` is the only name that makes sense (i.e., if it is an industry standard) and if adding any meaningful suffix (or changing the name) is not an appropriate option. + +image:icons/thumbs_down_solid.png[] Do not use underscores, hyphens, or any other non-alphanumeric characters. + +image:icons/thumbs_down_solid.png[] Do not use Hungarian notation. Hungarian notation is the practice of including a prefix in identifiers to encode some metadata about the parameter, such as the data type of the identifier: + +|======================= +|*Prefix* |*Definition* +|b |boolean +|e |enum +|txt |text boxes +|======================= + +e.g: +[source, c#] +---- + bool bIsActive = true; +---- + +image:icons/thumbs_down_solid.png[] Avoid using identifiers that conflict with keywords of widely used programming languages. + +image:icons/thumbs_down_solid.png[] Do not use abbreviations or contractions as part of identifier names. + +image:icons/thumbs_down_solid.png[] Do not use any acronyms that are not widely accepted, and even if they are, only when necessary. + +image:icons/thumbs_down_solid.png[] Do not use the "Ex" (or a similar) suffix for an identifier to distinguish it from an earlier version of the same `API`. + +image:icons/thumbs_down_solid.png[] Do not use C# reserved words as names. + + +== Names of Assemblies and DLLs + +An assembly is the unit of deployment and identity for managed code programs. Although assemblies can span one or more files, typically an assembly maps one-to-one with a Dynamic Link Library (DLL). A DLL is a library that contains code and data that can be used by more than one program at the same time. + +This section describes DLL naming conventions, which then can be mapped to assembly naming conventions. + +image:icons/thumbs_up_solid.png[] Choose names for your assembly DLLs that suggest large chunks of functionality, such as `System.Data`. + +Assembly and DLL names don’t have to correspond to namespace names, but it is reasonable to follow the namespace name when naming assemblies. A good rule of thumb is to name the `DLL` based on the common prefix of the assemblies contained in the assembly. For example, an assembly with two namespaces, `MyCompany.MyTechnology.FirstFeature` and `MyCompany.MyTechnology.SecondFeature`, could be called `MyCompany.MyTechnology.dll`. + +image:icons/thumbs_up_solid.png[] Consider naming DLLs according to the following pattern: + +`...dll` + +== General coding style + +* Source files: One namespace and one class per code file. + +* Braces: On new line. Always use braces when optional. + +[source, c#] +---- + if(i == 0) + { + + } +---- + +* Indention: Use tabs with size of 4. + +* Comments: + +** image:icons/thumbs_up_solid.png[] Use `//` for simple comment or `///` for summaries. + +** image:icons/thumbs_down_solid.png[] Do not use `/* … */` and do not flower box. + +* Use built-in C# native data types instead of .NET Common Type System (CTS) types (string instead of String) + +* Avoid changing default type in Enums. + +* Use `base` or `this` only in constructors or within an override. + +* Always check for null before invoking events. + +* Avoid using `Finalize`. Use C# Destructors and do not create Finalize() method. + +* Suggestion: Use blank lines, to make it much more readable by dividing it into small, easy-to-digest sections: + +** Use a single blank line to separate logical groups of code, such as control structures. +** Use two blank lines to separate method definitions + +* Avoid long code lines when possible to make reading much more easier: + +[source, c#] +---- + var result = await DbContext + .Set() + .AddAsync(entity) + .ConfigureAwait(false); +---- + +[options="header"] +|======================= +|*Case*|*Convention* +|Source File| Pascal case. Match class name and file name +|Namespace| Pascal case +|Class| Pascal case +|Interface| Pascal case +|Generics| Single capital letter (T or `K`) +|Methods| Pascal case (use a Verb or Verb+Object) +|Public field|Pascal case +|Private field|Camel case with underscore (_) prefix +|Static field|Pascal case +|Property|Pascal case. Try to use get and and set convention {get;set;} +|Constant|Pascal case +|Enum|Pascal case +|Variable (inline)|Camel case +|Param|Camel case +|======================= + + +== Use of Region guideline +Regions can be used to collapse code inside Visual Studio .NET. Regions are ideal candidates to hide boiler plate style code that adds little value to the reader on your code. Regions can then be expanded to provide progressive disclosure of the underlying details of the class or method. + + +image:icons/thumbs_down_solid.png[] Do Not regionalise entire type definitions that are of an important nature. Types such as enums (which tend to be fairly static in their nature) can be regionalised – their permissible values show up in Intellisense anyway. + +image:icons/thumbs_down_solid.png[] Do Not regionalise an entire file. When another developer opens the file, all they will see is a single line in the code editor pane. + +image:icons/thumbs_up_solid.png[] Do regionalise boiler plate type code. + +== Use of Comment guideline +Code is the only completely reliable documentation: write “good code” first! + +=== Avoid Unnecessary comments + + +* Choosing good names for fields, methods, parameters, etc. “let the code speak” (K. Beck) by itself reducing the need for comments and documentation + +* Avoid “repeating the code” and commenting the obvious + +* Avoid commenting “tricky code”: rewrite it! If there’s no time at present to refactor a tricky section, mark it with a `TODO` comment and schedule time to take care of it as soon as possible. In Visual Studio you can even navigate through the TODOs so you'll never forget what needs to be done. + +=== Effective comments + +* Use comments to summarize a section of code + +* Use comments to clarify sensitive pieces of code + +* Use comments to clarify the intent of the code + +* Bad written or out-of-date comments are more damaging than helpful: + +* Write clear and effective comments + +* Pay attention to pre-existing comments when modifying code or copying&pasting code + + + +== References +Here are some interesting references to continue learning about this topic: + +* https://docs.microsoft.com/en-us/dotnet/standard/design-guidelines/naming-guidelines[Naming guidelines - Microsoft Docs] + +* https://docs.microsoft.com/en-us/dotnet/standard/design-guidelines/general-naming-conventions[General naming conventions - Microsoft Docs] + +* https://docs.microsoft.com/en-us/dotnet/standard/design-guidelines/capitalization-conventions[Capitalization conventions - Microsoft Docs] + +* https://docs.microsoft.com/en-us/dotnet/standard/design-guidelines/names-of-assemblies-and-dlls[Assembly and Name Spaces conventions - Microsoft Docs] + +* https://docs.microsoft.com/es-es/troubleshoot/windows-client/deployment/dynamic-link-library[What is a DLL - Microsoft Docs] \ No newline at end of file diff --git a/source/documentation/environment.asciidoc b/source/documentation/environment.asciidoc new file mode 100644 index 00000000..c69e9ffc --- /dev/null +++ b/source/documentation/environment.asciidoc @@ -0,0 +1,459 @@ +:toc: + += Environment Setup + +toc::[] + +== Overview + +This guide will explain how to configure the full system environment to make the Devon4Net.Template.WebAPI operate in Visual Studio Code. + +== Required software +https://code.visualstudio.com/[Visual Studio Code] + +https://dotnet.microsoft.com/en-us/download[.Net Core SDK] + +https://marketplace.visualstudio.com/items?itemName=ms-vscode.csharp[C# Extension for VS Code] + +== Setting up the environment + +=== For Windows + +==== Visual Studio Code +Download and install *Visual Studio Code*: + +. Download the latest version https://code.visualstudio.com/[here] ++ +.Download Page +image::images/environment-1.png[] + + +. Open the downloaded installer, accept the terms and conditions, and then click next: ++ +.License Agreement +image::images/environment-2.png[] + +. Select the location where Visual Studio Code will be installed. : ++ +.Destination Folder +image::images/environment-3.png[] + +. Check the option if you do not wish to create a Start Menu folder, then click next: ++ +.Start Menu Setup +image::images/environment-4.png[] + +. Check the boxes next to the options you wish to install for your environment, and then click next: ++ +TIP: Select the "Open with Code" options; this is a really useful tool, and if you don't mark them, you won't be able to configure them again unless you reinstall the application. ++ +.Setup Additional Tasks +image::images/environment-5.png[] + +. Select next to begin the installation: ++ +.Final Setup +image::images/environment-6.png[] + +. Select finish to end the installation and launch visual studio code: ++ +.Completed Instalation +image::images/environment-7.png[] + +==== .Net Core SDK + +Download and install *.Net Core SDK*: + +. Download https://dotnet.microsoft.com/en-us/download[.Net SDK x64 for .Net 6.0] ++ +.Download Page .Net 6.0 +image::images/environment-8.png[] + +. Open the downloaded installer, and click on the install button: ++ +.Microsoft .NET SDK Installer +image::images/environment-9.png[] + +. Click in the close button to finish the installation: ++ +.Microsoft .NET SDK Installer +image::images/environment-10.png[] + +. To verify the installation, open a command prompt and enter the following command: ++ +[source, console] +---- +dotnet --version +---- ++ +.CMD dotnet command +image::images/environment-11.png[] + +==== OmniSharp extension +Download and install *C# extension (by OmniSharp)*: + +. Open Visual Studio, go to the extensions section (1), search for C# extensions (2) and install the C# extension by OmniSharp: ++ +.Extensions Site in Visual Code Studio +image::images/environment-12.png[] + +=== For Linux Systems + +This guide is intended for Ubuntu/Debian distributions; if you are using another Linux distribution, please refer to the https://code.visualstudio.com/docs/setup/linux[official Visual Code Studio documentation] + +==== Visual Studio Code +Download and install *Visual Studio Code*: + +. Download the latest version https://code.visualstudio.com/download[here] ++ +.Download Page +image::images/environment-15.png[] + +. To install, open a terminal within the Downloads folder (or the location where the binary was downloaded) and run the following command: ++ +[source, bash] +---- +sudo apt install ./.deb + +# If you're on an older Linux distribution, you will need to run this instead: +# sudo dpkg -i .deb +# sudo apt-get install -f # Install dependencies +---- ++ +Where `` is the name of the binary that was downloaded in step 1. ++ +.Terminal command example +image::images/environment-16.png[] + +. Then update the package cache and install the package using: ++ +[source, bash] +---- +sudo apt install apt-transport-https +sudo apt update +sudo apt install code # or code-insiders +---- + +==== .Net Core SDK + +Download and install *.Net Core SDK*: + +. To install, open a terminal and run the following command: ++ +[source, bash] +---- +sudo apt-get update; \ +sudo apt-get install -y apt-transport-https && \ +sudo apt-get update && \ +sudo apt-get install -y dotnet-sdk-6.0 +---- ++ +WARNING: If you receive an error message similar to Unable to locate package dotnet-sdk-6.0, see the https://docs.microsoft.com/en-us/dotnet/core/install/linux-ubuntu#apt-troubleshooting[APT troubleshooting section] of the official documentation. + +. To verify the installation, open a terminal and enter the following command: ++ +[source, console] +---- +dotnet --version +---- ++ +.CMD dotnet command +image::images/environment-17.png[] + +NOTE: This guide is intended for Ubuntu/Debian distributions; if you are using another Linux distribution, please refer to the https://docs.microsoft.com/en-us/dotnet/core/install/[Official Microsoft Documentation] + +==== OmniSharp extension +Download and install *C# extension (by OmniSharp)*: + +. Open Visual Studio, go to the extensions section (1), search for C# extensions (2) and install the C# extension by OmniSharp: ++ +.Extensions Site in Visual Code Studio +image::images/environment-12.png[] + +=== For MacOS + +==== Visual Studio Code + +Download and install *Visual Studio Code*: + +. Download the latest version https://code.visualstudio.com/download[here] ++ +.Download Page +image::images/environment-18.png[] + +. Allow the download for this website by clicking the Allow button: ++ +.Download Page +image::images/environment-19.png[] + +. Go to the Downloads folder and Drag `Visual Studio Code.app` to the Applications folder, making it available in the macOS Launchpad: ++ +.MacOS Launchpad +image::images/environment-21.png[] + +. Launch Visual Studio Code: ++ +When you initially start Visual Studio Code, you must authorize the program to launch by clicking the open button. ++ +.Opening VSCode +image::images/environment-20.png[] ++ +TIP: Add VS Code to your Dock by right-clicking on the icon, located in the Dock, to bring up the context menu and choosing Options, Keep in Dock + +==== .Net Core SDK + +. Download https://dotnet.microsoft.com/en-us/download[.Net 6.0 SDK] for your cpu architecture (x64 or Arm64). ++ +.Download Page .Net 6.0 +image::images/environment-22.png[] + +. Allow the download clicking the allow button in the next window: ++ +.Download Page .Net 6.0 +image::images/environment-23.png[] + +. Go to the downloads folder, open the downloaded installer, and click on the continue button: ++ +.Microsoft .NET SDK Installer +image::images/environment-24.png[] + +. Select the destination disk where you want to install the Microsoft .NET SDK, and click continue: ++ +.Microsoft .NET SDK Installer +image::images/environment-25.png[] + +. Click on the install button to perform a standard installation: ++ +.Microsoft .NET SDK Installer +image::images/environment-26.png[] + +. Type your credentials and click the Install Software button to begin the installation: ++ +.Microsoft .NET SDK Installer +image::images/environment-27.png[] + +. To verify the installation, open a terminal and enter the following command: ++ +[source, console] +---- +dotnet --version +---- ++ +.CMD terminal command +image::images/environment-28.png[] + +==== OmniSharp extension + +Download and install *C# extension (by OmniSharp)*: + +. Open Visual Studio, go to the extensions section (1), search for C# extensions (2) and install the C# extension by OmniSharp: ++ +.Extensions Site in Visual Code Studio +image::images/environment-12.png[] + +== Devon4net.Web.Api.Template + +=== For Windows + +. Open a project: +* Open Visual Studio Code. +* Click on the Explorer icon on the left menu and then click **Open Folder**. + +* Select the folder you want your C# project to be in and click **Select Folder**. For our example, we'll create a folder for our project named `'ApiTest'`. + +. Initialize a C# project: +* Open the Integrated Terminal from Visual Studio Code by typing `Left CTRL + backtick`. Alternatively, you can select **View** > **Terminal** from the main menu. +* You must select Command Prompt instead of PowerShell: ++ +.CMD in Visual Code Studio +image::images/environment-13.png[] + +* In the terminal window, type: ++ +[source, console] +---- +dotnet new -i Devon4Net.WebAPI.Template +---- + +* This will install the Devon4Net.WebAPI.Template with the latest version, next to create your project you must run the following command. ++ +[source, console] +---- +dotnet new Devon4NetAPI +---- + +. Run the "ApiTest" program: +* Go to the path where the Program.cs file is found typing the following command: ++ +[source, console] +---- +cd Templates\WebAPI\Devon4Net.Application.WebAPI +---- ++ +And then type: ++ +[source, console] +---- +dotnet run +---- + +* You can now test the template by going to the swagger page at: https://localhost:8085/swagger/index.html. + +You may now start working with C# and the devon4net api template in the Visual Studio Code environment. + +=== For Linux Systems + +. Open a project: +* Open Visual Studio Code. +* Click on the Explorer icon on the left menu and then click **Open Folder**. + +* Select the folder you want your C# project to be in and click **Select Folder**. For our example, we'll create a folder for our project named `'ApiTest'`. + +. Initialize a C# project: +* Open the Integrated Terminal from Visual Studio Code by typing `Left CTRL + backtick`. Alternatively, you can select **View** > **Terminal** from the main menu. + +* In the terminal window, type: ++ +[source, console] +---- +dotnet new -i Devon4Net.WebAPI.Template +---- + +* This will install the Devon4Net.WebAPI.Template with the latest version, next to create your project you must run the following command. ++ +[source, console] +---- +dotnet new Devon4NetAPI +---- + +. Run the "ApiTest" program: +* Go to the path where the Program.cs file is found typing the following command: ++ +[source, console] +---- +cd Templates/WebAPI/Devon4Net.Application.WebAPI +---- ++ +And then type: ++ +[source, console] +---- +dotnet run +---- + +* You can now test the template by going to the swagger page at: https://localhost:8085/swagger/index.html. + +You may now start working with C# and the devon4net api template in the Visual Studio Code environment. + +=== For MacOS + +. Open a project: +* Open Visual Studio Code. +* Click on the Explorer icon on the left menu and then click **Open Folder**. + +* Select the folder you want your C# project to be in and click **Select Folder**. For our example, we'll create a folder for our project named `'ApiTest'`. + +. Initialize a C# project: +* Open the Integrated Terminal from Visual Studio Code by typing `Left CTRL+ Left Shift + backtick`. Alternatively, you can select **View** > **Terminal** from the main menu. + +* In the terminal window, type: ++ +[source, console] +---- +dotnet new -i Devon4Net.WebAPI.Template +---- + +* This will install the Devon4Net.WebAPI.Template with the latest version, next to create your project you must run the following command. ++ +[source, console] +---- +dotnet new Devon4NetAPI +---- + +. Run the "ApiTest" program: +* Go to the path where the Program.cs file is found typing the following command: ++ +[source, console] +---- +cd Templates/WebAPI/Devon4Net.Application.WebAPI +---- ++ +And then type: ++ +[source, console] +---- +dotnet run +---- + +* You can now test the template by going to the swagger page at: https://localhost:8085/swagger/index.html. + +You may now start working with C# and the devon4net api template in the Visual Studio Code environment. + +==== Troubleshoot + +It's possible that when you execute the program, you'll get the following error: + +image::images/Exception-DevonWebAPI-MacEnvironment.png[] + +That is why Kestrel does not support HTTP/2 with TLS in macOS. +To fix this, navigate to the `appsettings.json` file and disable the TLS protocol in the Kestrel server setup as follows: + +[source, json] +---- +{ + "devonfw": { + "Kestrel": { + "UseHttps": true, + "HttpProtocol": "Http1AndHttp2", //Http1, Http2, Http1AndHttp2, none + "ApplicationPort": 8085, + "SslProtocol": "none", //Tls12, Tls13, none. For Https2 Tls12 is needed + } + } +} +---- + +WARNING: HTTP/2 without TLS should only be used during app development. Production apps should always use transport security. + +== Debug + +. Open for example Program.cs by clicking on it. The first time you open a C# file in Visual Studio Code, OmniSharp will load in the editor. + +. To open the Debug view, click on the Debugging icon on the left side menu. + +. Visual Studio Code will prompt you to add the missing assets to build and debug your app. Select Yes. + +. Locate the green arrow at the top of the pane. Make sure the drop-down next to it has `.NET Core Launch (web)` selected. + +. Add a breakpoint to your project by clicking on the **editor margin** (the space on the left of the line numbers in the editor). + +. Select F5 or the green arrow to start debugging. The debugger stops execution of your program when it reaches the breakpoint you set in the previous step. + +* While debugging you can view your local variables in the top left pane or use the debug console. + +. Select the green arrow at the top to continue debugging, or select the red square at the top to stop. + +The following figure summarizes the most important points: + +.Debug mode in Visual Code Studio +image::images/environment-14.png[] + +Where: + +. Debug Section +. Launch button +. Break Point +. Debug Console +. Debug Navigation Buttons + +[NOTE] +==== +For more information and troubleshooting tips on .NET Core debugging with OmniSharp in Visual Studio Code, see https://github.com/OmniSharp/omnisharp-vscode/blob/master/debugger.md[Instructions for setting up the .NET Core debugger]. +==== + +== External links + +https://www.microsoft.com/net/core[.Net Core] + +https://code.visualstudio.com/docs/other/dotnet[Using .NET Core in Visual Studio Code] + +https://docs.microsoft.com/dotnet/core/tutorials/with-visual-studio-code[.Net Core in Visual Studio Code tutorial] diff --git a/source/documentation/faq.asciidoc b/source/documentation/faq.asciidoc new file mode 100644 index 00000000..888b8816 --- /dev/null +++ b/source/documentation/faq.asciidoc @@ -0,0 +1,65 @@ +:toc: + += Frecuently Asked Questions + +toc::[] +== Introduction +In this document you will find the most asked questions about devon4net framework. We divided the questions into different topics so you can easily navigate through all the information. + +== Configuration + +=== Is it possible to create a configuration for different environments? +In the same way that it is possible to use different runtime environments in a .Net project, you can also specify this environment to devon so you can set a different configuration for each one of them. + +For example, maybe you don't want to allow Swagger use in production. For that, you will need to create a separate `appsettings.Production.json` file with your wanted configuration, and set `Environment` property to `Production` in `devonfw` section in `appsettings.json` file. + +When changing this property to `Production`, only `appsettings.Production.json` will load as configuration. You will not be able to load other environment configurations such as `appsettings.Development.json`. + +To create a new environment configuration you can follow the next steps: + +==== Step 1: Add your new `appsettings.{environment}.json` file + +To add a new file, right click your startup project. And select `Add > New Item...` option. + +.Add a new item to your Startup Project +image::images/add_new_item.png[] + +Search for Item `App Settings File` and create it with the name `appsettings.{environment}.json`. For this example we will use + +.Create appsettings.Production.json file +image::images/create_production_appsettings.png[] + +==== Step 2: Set environment property to `{environment}` + +Navigate to `appsettings.json` and change property Environment to your desired environment. For this example we will specify `Production` for this example: + +[source, json] +---- +{ + "devonfw": { + "Environment": "Production", + } +} +---- + +NOTE: The configuration loaded will be `appsettings.json` and `appsettings.{environment}.json` being `{environment}` the `Environment` property set in `devonfw` section. + +=== Is there a way to add other configuration files? +In devon we allow you to specify an array of filenames and directory paths that will be loaded as configuration files to your project. That way you can store configuration in other places. + +[source, json] +---- +{ + "ExtraSettingsFiles": [ + "appsettingsExtra.json", + "/run/secrets/global", + "/app-configs/app/extra-settings.json" + ], +} +---- + +You will find this section in `appsettings.{environment}.json` + +* Put a file name like `appsettingsExtra.json` to load configuration placed inside the project directory. +* Put a directory path (relative/absolute/linux-like) like `/run/secrets/global` where there are many settings/secret files to load. +* Put a specific file name (with/without path) like `/app-configs/app/extra-settings.json`. \ No newline at end of file diff --git a/source/documentation/fonts/FontAwesome.otf b/source/documentation/fonts/FontAwesome.otf new file mode 100644 index 00000000..401ec0f3 Binary files /dev/null and b/source/documentation/fonts/FontAwesome.otf differ diff --git a/source/documentation/fonts/License.txt b/source/documentation/fonts/License.txt new file mode 100644 index 00000000..d46aa01a --- /dev/null +++ b/source/documentation/fonts/License.txt @@ -0,0 +1,34 @@ +Font Awesome Free License +------------------------- + +Font Awesome Free is free, open source, and GPL friendly. You can use it for +commercial projects, open source projects, or really almost whatever you want. +Full Font Awesome Free license: https://fontawesome.com/license/free. + +# Icons: CC BY 4.0 License (https://creativecommons.org/licenses/by/4.0/) +In the Font Awesome Free download, the CC BY 4.0 license applies to all icons +packaged as SVG and JS file types. + +# Fonts: SIL OFL 1.1 License (https://scripts.sil.org/OFL) +In the Font Awesome Free download, the SIL OFL license applies to all icons +packaged as web and desktop font files. + +# Code: MIT License (https://opensource.org/licenses/MIT) +In the Font Awesome Free download, the MIT license applies to all non-font and +non-icon files. + +# Attribution +Attribution is required by MIT, SIL OFL, and CC BY licenses. Downloaded Font +Awesome Free files already contain embedded comments with sufficient +attribution, so you shouldn't need to do anything additional when using these +files normally. + +We've kept attribution comments terse, so we ask that you do not actively work +to remove them from files, especially code. They're a great way for folks to +learn about Font Awesome. + +# Brand Icons +All brand icons are trademarks of their respective owners. The use of these +trademarks does not indicate endorsement of the trademark holder by Font +Awesome, nor vice versa. **Please do not use brand logos for any purpose except +to represent the company, product, or service to which they refer.** \ No newline at end of file diff --git a/source/documentation/fonts/fontawesome-webfont.eot b/source/documentation/fonts/fontawesome-webfont.eot new file mode 100644 index 00000000..e9f60ca9 Binary files /dev/null and b/source/documentation/fonts/fontawesome-webfont.eot differ diff --git a/source/documentation/fonts/fontawesome-webfont.svg b/source/documentation/fonts/fontawesome-webfont.svg new file mode 100644 index 00000000..855c845e --- /dev/null +++ b/source/documentation/fonts/fontawesome-webfont.svg @@ -0,0 +1,2671 @@ + + + + +Created by FontForge 20120731 at Mon Oct 24 17:37:40 2016 + By ,,, +Copyright Dave Gandy 2016. All rights reserved. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/source/documentation/fonts/fontawesome-webfont.ttf b/source/documentation/fonts/fontawesome-webfont.ttf new file mode 100644 index 00000000..35acda2f Binary files /dev/null and b/source/documentation/fonts/fontawesome-webfont.ttf differ diff --git a/source/documentation/fonts/fontawesome-webfont.woff b/source/documentation/fonts/fontawesome-webfont.woff new file mode 100644 index 00000000..400014a4 Binary files /dev/null and b/source/documentation/fonts/fontawesome-webfont.woff differ diff --git a/source/documentation/fonts/fontawesome-webfont.woff2 b/source/documentation/fonts/fontawesome-webfont.woff2 new file mode 100644 index 00000000..4d13fc60 Binary files /dev/null and b/source/documentation/fonts/fontawesome-webfont.woff2 differ diff --git a/source/documentation/home.asciidoc b/source/documentation/home.asciidoc new file mode 100644 index 00000000..043cf247 --- /dev/null +++ b/source/documentation/home.asciidoc @@ -0,0 +1,58 @@ + +:toc: preamble +:toc-title: Index + += devon4net + +toc::[] + +Welcome to devon4net's wiki, we'll learn more about this useful tool in this guide. +This wiki covers everything you'll need to get started with this tool, from an explanation of its architecture to instructions on how to use the templates and components, as well as information about the environment and code convection. +Because it's such a highly valuable tool, it is interesting to learn all of its complexities so you can get the most out of it. There are no limits to what you can achieve with devon4net. + +== Motivation + +Integrating young and senior developers into .net core is the most difficult task we face in our projects. +There are several frameworks and architectures available on the market. + +On the one hand, the goal is to develop an architecture that strikes a balance between best practices and current trends. +On the other hand, delivering a quick onboarding period while still using an architecture that allows us to expand while being productive. +In addition, the architecture must be market-compatible. This is what devon4net provides, which was built with a real clean layered architectural design. + +"Make it work, make it right, make it fast." +-- Kent Beck + +== Wiki's content + +=== https://github.com/devonfw/devon4net/wiki/architecture_guide[Architecture Overview] + +It consists of a detailed explanation of the architecture (onion design) in which our application is built. + +=== https://github.com/devonfw/devon4net/wiki/cobiGen[cobiGen] + +This section describes how to use cobiGen, a sophisticated source code generator. + +=== https://github.com/devonfw/devon4net/wiki/codeconvention[Coding Convention] + +About .Net Coding Standards documentation + +=== https://github.com/devonfw/devon4net/wiki/environment[Environment] + +Setup for starting an application with .Net + +=== https://github.com/devonfw/devon4net/wiki/howto[How to] + +In this page, you will find instructions for configuring your devonfw project, as well as guidelines for setting up some of its components. + + +=== https://github.com/devonfw/devon4net/wiki/packages[Packages] + +List of packages available on https://www.nuget.org/packages?q=devonfw[nuget.org] + +=== https://github.com/devonfw/devon4net/wiki/templates[Templates] + +A brief tutorial on how to set up the Devon4Net.WebAPI.Template + +=== https://github.com/devonfw/devon4net/wiki/userguide[Userguide] + +Rapid guide that contains everything you need to start developing your project with devon4net. \ No newline at end of file diff --git a/source/documentation/howto.asciidoc b/source/documentation/howto.asciidoc new file mode 100644 index 00000000..e2178755 --- /dev/null +++ b/source/documentation/howto.asciidoc @@ -0,0 +1,3309 @@ +:toc: + += How to use devon4net + +toc::[] +== Introduction + +As you may know, https://devonfw.com/website/pages/docs/devonfw-guide_devon4net.wiki_master-devon4net.asciidoc.html[devon4net] is a framework that will assist you in getting started on your.NET applications and integrating high end configurable components. + +This article contains information in the form of a step-by-step guide on how to do a variety of operations. + +== How to: Create a new devon4net project +In this part, you will learn you how to easily create a new project using devon4net libraries and start working on it. You can create a variety of applications thanks to the different templates available. There are also multiple ways to create a new project, we will show you the most common ways. + +NOTE: The configuration characteristics are not covered in this document. Please feel free to read the documentation for each component to discover how they work and the configuration options available. + +=== Command Line Interface (CLI) +This is the fastest and most efficient way. You will be installing and starting a project thanks to the template available in the NuGet Gallery using CLI. For this part you will need to have .NET 6.0 SDK installed. You can run the following command to check your version: + +[source, console] +---- +> dotnet --version +6.0.102 +---- + +If you don't get any response please follow the https://docs.microsoft.com/en-us/dotnet/core/install/[installation guide] provided by Microsoft to install the latest version of .Net SDK for your OS. + +==== Step 1 - Install the Template +Open your favourite terminal (Windows/Linux/macOS) and run the command showed below to install the latest version of the the https://www.nuget.org/packages/Devon4Net.WebAPI.Template/[devon4net web API template]: + +[source, console] +---- +> dotnet new --install Devon4Net.WebAPI.Template +The following template packages will be installed: + Devon4Net.WebApI.Template + +Success: Devon4Net.WebAPI.Template::6.0.3 installed the following templates: +Template Name Short Name Language Tags +------------------------------- ------------ -------- ------------------------------ +Devon4Net API solution template Devon4NetAPI [C#] devonfw/Devon4Net/Devon4NetAPI +---- + +We recommend you updating the template to the latest version. However, using the following option, you can select the version of your interest: +[source, console] +---- +> dotnet new --install Devon4Net.WebAPI.Template::6.0.3 +---- + +Now you will have the template available in your Visual Studio 2022. Just type `devon4net` in the search bar when creating a new project! + +.Devon4Net API template in VS2022 +image::images/api_template_ide.png[] + +==== Step 2 - Create a new project +To create a new project run the following command: +[source, console] +---- +> dotnet new Devon4NetAPI +The template "Devon4Net API solution template" was created successfully. +---- +This will create a project with the default name in the actual directory. If you want to specify the desired name and output directory you can specify the following options: +[source, console] +---- +> dotnet new Devon4NetAPI --name MyProject --output C:\Projects\MyProject +The template "Devon4Net API solution template" was created successfully. +---- + +You can do it also choosing the template when creating a new project in Visual Studio 2022 as shown in figure 1, and configuring the name and output directory as shown in figure 2. + +.Devon4Net API template in VS2022 +image::images/api_template_configure.png[] + +==== Step 3 - Run it +After running it with Kestrel you will be able to access to the swagger `index.html` and try the API in the following link: https://localhost:8085/swagger/index.html[https://localhost:8085/swagger/index.html] + +=== Create it from scratch in Visual Studio 2022 +This method is a little more time consuming, but it allows for a more customized configuration and project structure. You will be using Visual Studio 2022 to create the project and add everything you need by hand. + +==== Step 1 - Create a new project +Create a new ASP.NET Core Web API project using the template provided by Visual Studio. You can type `api` in the search bar and select it as shown in figure 3. + +.ASP.NET Core Web API template in VS2022 +image::images/api_template_create_project.png[] + +Once you go through all the initial configuration process, choosing a name, location and so on; you will find your project as shown in the next image. + +.Default ASP.NET Core Web API template structure +image::images/api_template_initial_structure.png[] + +You can delete both `WeatherForecastController.cs` and `WeatherForecast.cs` as they are an example in the template but we recommend you keeping them so you can try the API when done with all the steps. + +==== Step 2 - Add the NuGet reference +To install the NuGet package for the API Configuration we will use the Visual Studio package manager console. To open it, go to `View > Other Windows > Package Manager Console` as shown in the figure below. + +.Package Manager Console location in menu +image::images/api_template_package_manager.png[] + +Now you can run the following command. It will take a minute to download and install all the packages: +[source, console] +---- +PM> install-package Devon4Net.Infrastructure.WebAPI +---- +Once its done, you should be able to see the dependency in the Package Dependencies of the project. + +==== Step 3 - Set up your project + +Now you will need to add some configuration in the `Program.cs`. The following lines will initialize the configuration for the WebHostBuilder and configure the components that were imported with the NuGet installation respectively, making use of extensions methods for the `ServiceCollection` and `WebHostBuilder` classes: + +[source, c#] +---- +builder.WebHost.InitializeDevonFw(); +builder.Services.ConfigureDevonFw(builder.Configuration); +---- + +Now you'll need to configure the middlewares included with the following line: + +[source, c#] +---- +app.SetupMiddleware(builder.Services); +---- + +NOTE: Don't forget to import the package to be able to use this methods! + +It is not necessary, but we recommend to also setup the logger so you can keep track of the trace running: + +[source, c#] +---- +builder.Services.SetupLog(builder.Configuration); +---- + +The `Program.cs` will end up looking like this: + +[source, c#] +---- +using Devon4Net.Application.WebAPI.Configuration; +using Devon4Net.Application.WebAPI.Configuration.Application; +using Devon4Net.Infrastructure.Middleware.Middleware; + +var builder = WebApplication.CreateBuilder(args); + +builder.Services.AddControllers(); + +// devon4net +builder.WebHost.InitializeDevonFw(); +builder.Services.SetupLog(builder.Configuration); +builder.Services.SetupDevonfw(builder.Configuration); + +var app = builder.Build(); +app.UseHttpsRedirection(); + +// devon4net +app.SetupMiddleware(builder.Services); + +app.UseAuthorization(); + +app.MapControllers(); + +app.Run(); +---- + +==== Step 4 - Configure components + +The lines added on the previous step will need some configuration in the `appsettings.json`: + +[source, json] +---- +{ + "devonfw": { + "UseDetailedErrorsKey": true, + "UseIIS": false, + "UseSwagger": true, + "UseXsrf": true, + "UseModelStateValidation": true, + "Environment": "Development", + "ForceUseHttpsRedirection": false, + "Kestrel": { + "UseHttps": true, + "HttpProtocol": "Http1AndHttp2", //Http1, Http2, Http1AndHttp2, none + "ApplicationPort": 8085, + "SslProtocol": "Tls12", //Tls12, Tls13, none. For Https2 Tls12 is needed + "ExtraSettings": { + "KeepAliveTimeout": 120, //in seconds + "MaxConcurrentConnections": 100, + "MaxConcurrentUpgradedConnections": 100, + "MaxRequestBodySize": 28.6, //In MB. The default maximum request body size is 30,000,000 bytes, which is approximately 28.6 MB + "Http2MaxStreamsPerConnection": 100, + "Http2InitialConnectionWindowSize": 131072, // From 65,535 and less than 2^31 (2,147,483,648) + "Http2InitialStreamWindowSize": 98304, // From 65,535 and less than 2^31 (2,147,483,648) + "AllowSynchronousIO": true + } + }, + "IIS": { + "ForwardClientCertificate": true, + "AutomaticAuthentication": true, + "AuthenticationDisplayName": "" + } + } +} +---- + +And also in the `appsettings.Development.json`: + +[source, json] +---- +{ + "ExtraSettingsFiles": [ + "appsettingsExtra.json", + "Directory path", + "Specific file name" + ], + "KillSwitch": { + "UseKillSwitch": false, + "EnableRequests": false, + "HttpStatusCode": 403 + }, + "ConnectionStrings": { + "Default": "Todos", + "Employee": "Employee", + "RabbitMqBackup": "Add your database connection string here for messaging backup", + "MediatRBackup": "Add your databascere connection string here for messaging backup" + }, + "Certificates": { + "ServerCertificate": { + "Certificate": "", + "CertificatePassword": "" + }, + "ClientCertificate": { + "DisableClientCertificateCheck": true, + "RequireClientCertificate": false, + "CheckCertificateRevocation": true, + "ClientCertificates": { + "Whitelist": [ + "3A87A49460E8FE0E2A198E63D408DC58435BC501" + ] + } + } + }, + "Headers": { + "AccessControlExposeHeader": "Authorization", + "StrictTransportSecurityHeader": "", + "XFrameOptionsHeader": "DENY", + "XssProtectionHeader": "1;mode=block", + "XContentTypeOptionsHeader": "nosniff", + "ContentSecurityPolicyHeader": "", + "PermittedCrossDomainPoliciesHeader": "", + "ReferrerPolicyHeader": "" + }, + "Cors": [] +} +---- + +=== Unable to start devon4net template on macOS or older Windows Versions + +If you try to execute the devon4net template on macOS or an earlier version of Windows, such as Windows 7, you will receive the following error message: + +image::images/Exception-DevonWebAPI-MacEnvironment.png[] + +Because these operating systems lack ALPN(Application-Layer Protocol Negotiation) functionality, Kestrel does not handle HTTP/2 with TLS. + +To resolve this, navigate to 'appsettings.json' and change the Kestrel configuration as seen below: + +[source, json] +---- +{ + "devonfw": { + "UseDetailedErrorsKey": true, + "UseIIS": false, + "UseSwagger": true, + "UseXsrf": true, + "UseModelStateValidation": true, + "Environment": "Development", + "ForceUseHttpsRedirection": false, + "Kestrel": { + "UseHttps": true, + "HttpProtocol": "Http1AndHttp2", //Http1, Http2, Http1AndHttp2, none + "ApplicationPort": 8085, + "SslProtocol": "none", //Tls12, Tls13, none. For Https2 Tls12 is needed + "ExtraSettings": { + "KeepAliveTimeout": 120, //in seconds + "MaxConcurrentConnections": 100, + "MaxConcurrentUpgradedConnections": 100, + "MaxRequestBodySize": 28.6, //In MB. The default maximum request body size is 30,000,000 bytes, which is approximately 28.6 MB + "Http2MaxStreamsPerConnection": 100, + "Http2InitialConnectionWindowSize": 131072, // From 65,535 and less than 2^31 (2,147,483,648) + "Http2InitialStreamWindowSize": 98304, // From 65,535 and less than 2^31 (2,147,483,648) + "AllowSynchronousIO": true + } + }, + "IIS": { + "ForwardClientCertificate": true, + "AutomaticAuthentication": true, + "AuthenticationDisplayName": "" + } + } +} +---- + +WARNING: HTTP/2 without TLS should only be used during app development. Production apps should always use transport security. + +=== References +Here are some interesting references to continue learning about this topic: + +* https://docs.microsoft.com/en-us/dotnet/core/install/[Install .NET on your OS - Microsoft Docs] + +* https://docs.microsoft.com/es-es/dotnet/core/tools/[.NET CLI overview - Microsoft Docs] + +* https://docs.microsoft.com/es-es/dotnet/core/tools/dotnet-new-install[dotnet new --install option - Microsoft Docs] + +* https://docs.microsoft.com/es-es/dotnet/core/tools/dotnet-new[dotnet new - Microsoft Docs] + + +== How to: Create and add certificates to a project +In this part, you will learn how to easily create a new certificate and properly add it to your devon4net project. + + +=== Create a certificate using OpenSSL +In order to create our own certificate for development purposes we will be using https://github.com/openssl/openssl[OpenSSL] toolkit. To ensure correct behavior, make sure the tool is properly installed. + +NOTE: Please refer to the https://www.openssl.org/docs/man3.0/man1/[OpenSSL command documentation] to learn more about the commands used in this guide and how to install the toolkit. + +To run commands for OpenSSL, you will need to add OpenSSL to your environment, variables, or open a OpenSSL command prompt. + +NOTE: The working directory (directory where all files are created and readed) is the console actual path. Use `cd` command to go to your desired directory. + +==== Step 1 - Create a Certificate Authority (CA) +First we will need to create a Certificate Authority to sign the certificate. For that, we will run the following command which will create the certificate `RootCA.pem` and the corresponding private key `RootCA.key`. + +[source, console] +---- +> openssl req -x509 -nodes -new -sha256 -days 1024 -newkey rsa:2048 -keyout RootCA.key -out RootCA.pem -subj "/C=ES/ST=Valencia/L=Valencia/O=Certificates/CN=MyProjectCertificate.local" +---- + +Now we will create the public key `RootCA.crt` for the certificate by running the following command: + +[source, console] +---- +> openssl x509 -outform pem -in RootCA.pem -out RootCA.crt +---- + +If you want to export the certificate you can run the command: + +[source, console] +---- +> openssl pkcs12 -export -out RootCA.pfx -inkey RootCA.key -in RootCA.crt +---- + +==== Step 2 - Create a Certificate signed by the CA + +To create a new certificate run the following command: +[source, console] +---- +> openssl req -new -nodes -newkey rsa:2048 -keyout localhost.key -out localhost.csr -subj "/C=ES/ST=Valencia/L=Valencia/O=Certificates/CN=localhost.local" +---- + +Before signing it, create a `domains.ext` that contains the following: + +[source, txt] +---- +authorityKeyIdentifier=keyid,issuer +basicConstraints=CA:FALSE +keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment +subjectAltName = @alt_names +[alt_names] +DNS.1 = localhost +DNS.2 = localhost.local +DNS.3 = 127.0.0.1 +DNS.4 = fake1.local +DNS.5 = fake2.local +---- + +Once the files are created, you'll need to sign the certificate with the CA we created earlier: +[source, console] +---- +> openssl x509 -req -sha256 -days 1024 -in localhost.csr -CA RootCA.pem -CAkey RootCA.key -CAcreateserial -extfile domains.ext -out localhost.crt +---- + +Run the next command to export the certificate: + +[source, console] +---- +> openssl pkcs12 -export -out localhost.pfx -inkey localhost.key -in localhost.crt +---- + +You will end up having something like this: + +.Certification Authority (left) and localhost certificate signed by CA (right) +image::images/certificates.png[] + +=== Add certificates to a devon4net project +Once you have created a certificate or in case you already have yours, you can add it to your project thanks to devon4net tools. + +==== Step 1 - Add it to your project + +Locate the Certificates directory in your startup project. If it doesn't exist, please create it and drop your certificate `.pfx` as shown in figure 2. + + +.Certificates directory in startup project +image::images/certificates_add.png[] + + +==== Step 2 - Configure your appsettings + +Now configure your certificate in `appsettings.Development.json`. For that, you'll need to specify the file name and the password you chose. Look for the `ServerCertificate` configuration and add something like this: + +[source, json] +---- +"Certificates": { + "ServerCertificate": { + "Certificate": "localhost.pfx", + "CertificatePassword": "12345" + }, + "ClientCertificate": { + "DisableClientCertificateCheck": true, + "RequireClientCertificate": false, + "CheckCertificateRevocation": true, + "ClientCertificates": { + "Whitelist": [ + "3A87A49460E8FE0E2A198E63D408DC58435BC501" + ] + } + } +}, +---- + +=== References +Here are some interesting references to continue learning about this topic: + +* https://github.com/openssl/openssl[OpenSSL] + +* https://www.openssl.org/docs/man1.0.2/man1/openssl-req.html[`req` command documentation - OpenSSL Docs] + +* https://www.openssl.org/docs/man1.0.2/man1/x509.html[`x509` command documentation - OpenSSL Docs] + +* https://www.openssl.org/docs/man3.0/man1/pkcs12.html[`pkcs12` command documentation - OpenSSL Docs] + +== How to: Setup JWT + +As you may have learned at this point you can set up JWT component in a number of different ways according your needs. For that you'll need to configure your `appsettings.json`. + +NOTE: Please read documentation about JWT component first to learn what you need to do to use it in your project. + +Assuming that you already have the JWT component correctly installed and available in our project let's start thinking about how we can put it to good use. + +=== Configuration + +We can configure it to work either with a secret key or a certificate. + +If you choose certificate, you will need to add a certificate to your project, and specify the password and the encryptionAlgorithm used. You can learn how to do it following the tutorial included in this document. + +If you specify both, the secret key will take priority. + +For example lets specify the next: + +.JWT configuration example +image::images/json_jwt_example.png[] + +NOTE: The property `SecretKey` needs to be an encrypted key using the algorithm specified. + +This would create the following configuration: + +* A token with audience and issuer equal to `devon4net`. +* It will expire in 60 minutes +* It will validate the signature and if the token is valid in time +* It will require tokens that are signed, and have both expiration time and audience specified. +* It will use the secret key encrypted with SHA 512 + +=== Claims + +Json Web Tokens work with claims. A Claim is a piece of information about a subject. It is similar to a key-value pair, where the value will be the claim type, such as the name or the role of an authenticated user. This claims are stored inside a JSON and then encrypted forming the JWT. + +In .Net we can create Claims using the `Claim` class avaiable in `System.Security.Claims`. It has many constructors but the most important is the following one, where you can create a Claim based on two strings. + +[source, c#] +---- +var nameClaim = new Claim(ClaimType.Name, "DevonUser"); +var roleClaim = new Claim(ClaimType.Role, "Administrator"); +---- + +You can choose between a variety of claim types thanks to the `ClaimType` class. As you can see in the previous piece of code, in this case we have asserted a name and a role in two claims. This could be for a user, for example. + +=== JwtHandler + +In JWT component we have a handler that is cofigured on the installation of the package and can be injected for use in any wanted service. This is the `JwtHandler`. This handler will allow us to manipulate, encrypt and extract information from Json Web Tokens. + +|==== +|*Return Type* |*Method Name* |*Parameters* |*Description* +|string |CreateJwtToken |List clientClaims |Returns the encrypted jwt given a list of claims. +|List |GetUserClaims |string jwtToken |Returns a list of claims given an encrypted token. +|string |GetClaimValue |List claimList, string claim |Returns the value of a claim given a list of claims and the type of the claim to recover formatted as a string. +|string |GetClaimValue |string token, string claim |Returns the value of a claim given an encrypted token and the type of the claim to recover formatted as a string. +|SecurityKey |GetIssuerSigningKey |- |Returns the issuer's signing key. +|bool |ValidateToken |string jwtToken, out ClaimsPrincipal claimsPrincipal, out SecurityToken securityToken |Returns true if the token is valid. +|string |CreateRefreshToken |- |Creates a refresh token for the JWT token. +|==== + +=== Video + +=== References +Here are some interesting references to continue learning about this topic: + +* https://auth0.com/docs/secure/tokens/json-web-tokens/json-web-token-claims[JSON Web Token Claims - auth0] + +* https://docs.microsoft.com/es-es/dotnet/api/system.security.claims.claim?view=net-6.0[Claim Class - Microsoft Docs] + +* https://docs.microsoft.com/es-es/dotnet/api/system.security.claims.claimtypes?view=net-6.0[ClaimTypes Class - Microsoft Docs] + + +== How to: Setup security and roles in API controllers + +In this part of the document, you will learn to use the different attributes over the controller methods that manage end-points. This attributes are provided by .Net core libraries and can be used to specify the behavior of Web API controllers and action methods. + +=== Attributtes +You can use a large number of attributes, some are optional, for example to define the route of end-points `[Route("/GetSomething")]` and other are required, like `[ApiController]` to indicate that the class is an API controller. + +NOTE: We will be explaining the security related attributes. Those that are specific to the controllers will not be mentioned. + +==== [HttpOptions] + +This attribute identifies an API controller end-point that support the HTTP OPTIONS request. The HTTP OPTIONS method is used to get information about the communication options available for a specific URL or server. + +NOTE: Please do your research on this method if you are not familiar with it. + +==== [AllowAnonymous] + +`AllowAnonymous` allows any type of user (authorized or unauthorized) to access the information provided by the end-point. This attribute can be specified for controller class or for individual end-points. Specifying it for individual end-points will override the controller attribute. An example could be: + +[source, c#] +---- +[HttpGet] +[AllowAnonymous] +[Route("/v1/getsomething")] +public async Task GetSomething() +{ + ... +} +---- + +==== [Authorize] + +`Authorize` only enables you to restrict access to requests with an authorization specified in the header. This attribute can be specified for controller class or for individual end-points. Specifying it for individual end-points will override the controller attribute. You can specify different properties to the attribute: + +|==== +|*Property* |*Type* |*Description* |*Example* +|`AuthenticationSchemes` |List of strings separated by comma |List of schemes from which user info is constructed |`[Authorize(AuthenticationSchemes = "Bearer")]` +|`Policy` |String |Policy name that determines access to the resource |`[Authorize(Policy = "MyPolicy")]` +|`Roles` |List of strings separated by comma |List of roles allowed to access |`[Authorize(Roles = "User")]` +|==== + +For example, lets create a controller that is authorized only for users with role 'Admin' and 'Tester' provided in 'Bearer' type authentication: + +[source, c#] +---- +[ApiController] +[Route("[controller]")] +[Authorize(AuthenticationSchemes = "Berarer", Roles = "Admin,Tester")] +public class DebugController: ControllerBase +{ + ... +} +---- + +==== [EnableCors] & [DisableCors] + +NOTE: Please refer to the CORS component documentation to learn everything about CORS. + +You can enable a Cors policy for controller or individual end-points. Specifying it for individual end-points will override the controller attribute. You will need to specify the policy you want to enable. This policy will need to be described in the `appsettings.{environment}.json`. + +For example, lets create a CORS policy named 'CorsPolicy' and enable it for a controller, and disable it for a method: + +[source, json] +---- +"Cors": //[], //Empty array allows all origins with the policy "CorsPolicy" +[ + { + "CorsPolicy": "CorsPolicy", + "Origins": "http://localhost:4200,https://localhost:4200,http://localhost,https://localhost;http://localhost:8085,https://localhost:8085", + "Headers": "accept,content-type,origin,x-custom-header,authorization", + "Methods": "GET,POST,HEAD,PUT,DELETE", + "AllowCredentials": true + } +], +---- + +[source, c#] +---- +[ApiController] +[Route("[controller]")] +[EnableCors("CorsPolicy")] +public class MyController: ControllerBase +{ + ... + [HttpGet] + [Route("/v1/getsomething")] + [DisableCors] + public async Task GetSomething() + { + ... + } + ... +} +---- + +=== References +Here are some interesting references to continue learning about this topic: + +* https://docs.microsoft.com/en-us/aspnet/core/security/authorization/introduction?view=aspnetcore-6.0[Introduction to authorization in ASP.NET Core - Microsoft Docs] + +* https://docs.microsoft.com/es-ES/dotnet/api/microsoft.aspnetcore.authorization?view=aspnetcore-6.0[Authorization Namespace - Microsoft Docs] + +* https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/OPTIONS[HTTP OPTIONS - MDN Web Docs] + +== How to: Configure and use Keycloak server + +=== What is Keycloak? + +Keycloak is an open-source tool that provides identity and access management providing highly secure properties to your application. It supports multiple protocols such as OAuth and OpenID. It has full support for SSO (Single Sign-On and Single Sign-Out) and third party Social Identity Providers such as Google, Twitter, Facebook... + +You can also connect it to some type of user database if you already have one for your client. This allows you to interconnect multiple applications through same users and data. + +One of the most interesting features is the GUI available through and end-point that allows you to configure and manage your Keycloak settings and properties. + +Long story short, Keycloak is a server that manages all your user related interactions, such as roles, groups, access tokens... so you can focus in developing your application and don't have to reinvent the wheel. + +=== Docker Image + +For this example we will be running the Keycloak docker image and exposing it in a local port. + +NOTE: Please make sure you have Docker installed in your machine before running the command. + +To start the Keycloak Server run the following command: + +[source, console] +---- +docker run -p 8080:8080 -e KEYCLOAK_ADMIN=admin -e KEYCLOAK_ADMIN_PASSWORD=admin quay.io/keycloak/keycloak:18.0.1 start-dev +---- + +WARNING: This whole guide is meant to be used with the Keycloak Server version `18.0.1`. It may not work in the same way in future versions. + +This will start the keycloak server in a docker image. It will be availabe in your localhost port 8080. As you can also see by the command, it will create an initial admin user with username `admin` and password `admin`. You can sign in navigating to the address http://localhost:8080/admin/[localhost:8080] and using this initial credentials. + +.Keycloak Sign In +image::images/keycloak_sign_in.png[] + +=== Realms + +In Keycloak, a realm is the same as an environment. It enables the creation of exclusive groups of users and applications. In Keycloak, there is just one realm by default, named master. This is for managing Keycloak only, therefore don't use it for your own programs. + +To create a realm you can hover the small arrow where it says `Master` in the dashboard and click on `Add realm`. + +.Create a realm in keycloak +image::images/keycloak_create_realm.png[] + +Choose a name, for this example we will name it `MyRealm`, and then click `Create`. + +Now when your realm is selected, you will be able to configure it through the `Realm Settings` tab in the left side menu. + +NOTE: Please visit the Keycloak documentation to learn more about how you can configure it and what options do you have. + +=== Clients + +A client, in Keycloak is equivalent to an application. You can add multiple applications and all can use the same users, groups, roles... + +.Create a client in keycloak +image::images/keycloak_create_client.png[] + +Now fill the form choosing at least a required client id. You can also select the protocol you will be using: + +* `OpenID connect` allows Clients to verify the identity of the End-User based on the authentication performed by an Authorization Server. +* `SAML` enables web-based authentication and authorization scenarios including cross-domain single sign-on (SSO) and uses security tokens containing assertions to pass information. + +.Create a client in keycloak +image::images/keycloak_set_client.png[] + +=== Users + +To create a new user follow the next steps: + +1. Log into the http://localhost:8080/admin/master/console/#/realms[Keycloak admin console] + +2. Select the Realm in which you want to create users: ++ +.Keycloak administrator console +image::images/keycloak_user_1.png[] + +3. Navigate to the *Users* section (1) in the left-side bar, then the *Add user* button (2): ++ +.Add a user in Keycloak +image::images/keycloak_user_2.png[] + +4. Complete the fields (1) and click the *Save* button (2): ++ +.Add a user in Keycloak +image::images/keycloak_user_3.png[] ++ +- The only required field is the username. +- The required user actions field refers to some action that the user must perform upon first logging in. + +5. Set a password for the user: ++ +.Set credentials to a user in Keycloak +image::images/keycloak_user_4.png[] ++ +- Navigate to the *Credentials* tab (1). +- Enter a password (2). +- Confirm the password (3). +- (*Optional*) +Change the switch to on if you want the user to change their password after the first login (4). +- Click the *Set Password* button to confirm the changes (5). + +=== Groups + +Groups in Keycloak allow you to manage a common set of attributes and role mappings for a set of users. Let's create a new group and add some users inside: + +1. Click the *Groups* section (1) in the left-side bar, then the *New* button (2): ++ +.Create a group in Keycloak +image::images/keycloak_group_1.png[] + +2. Insert the name of the group and then click the *Save* button: ++ +.Create a group in Keycloak +image::images/keycloak_group_2.png[] + +3. Groups are hierarchical. A group can have many subgroups, but a group can only have one parent. Subgroups inherit the attributes and role mappings from the parent. This applies to the user as well. By clicking in a group (1) and then clicking the *New* button (2), you can create a subgroup. ++ +.Create a subgroup in Keycloak +image::images/keycloak_group_3.png[] ++ +For example, you could have something like this: ++ +.Create a group in Keycloak +image::images/keycloak_group_4.png[] + +4. Add users to the groups: + +- Navigate to the *Users* section (1) in the left-side bar, then select the user you want to add to a group and click on the *Edit* button (2): ++ +.Add users to a group in Keycloak +image::images/keycloak_group_5.png[] + +- Click the *Groups* tab (1), select the group in which the user should be added (2), and then click the *Join* button (3): ++ +.Add users to a group in Keycloak +image::images/keycloak_group_6.png[] + +- You will see something like this: ++ +.Add users to a group in Keycloak +image::images/keycloak_group_7.png[] + +=== Roles + +==== Realm Roles + +Realm-level roles are a global namespace to define your roles. To add a new Real Role you have to: + +1. Navigate to the *Roles* section in the left-side bar (1), and click the *Add Roles* button (2): ++ +.Create a new Realm Role in Keycloak +image::images/keycloak_role_1.png[] + +2. Input a role name and click the *Save* button: ++ +.Create a new Realm Role in Keycloak +image::images/keycloak_role_2.png[] + +- The description field is not required + +3. Now you may add users to that role as follows: +- Navigate to the *Users* section (1) and select the *Edit* button (2) for the user to whom you want to assign the role: ++ +.adding a Realm Role to a user in Keycloak +image::images/keycloak_role_3.png[] + +- Select the *Role Mappings* tab (1), select the Role you want to assign (2) and then click the *Add selected* button (3): ++ +.adding a Realm Role to a user in Keycloak +image::images/keycloak_role_4.png[] + +==== Client Roles + +Client roles are basically a namespace dedicated to a client. Each client gets its own namespace. Client roles are managed under the Roles tab under each individual client: + +.Creating a Client Role in Keycloak +image::images/keycloak_role_5.png[] + +Input a role name and click the *Save* button: + +.Creating a Client Role in Keycloak +image::images/keycloak_role_6.png[] + +For adding the Client Role to an user: + +Navigate to the *Users* section (1) and select the correct user to asign the role, select the *Role Mappings* tab (2), in the *Client Roles* section select the Client (3), select the desired Role to assign (4) and click the *Add selected* button (5) + +.adding a Client Role to a user in Keycloak +image::images/keycloak_role_7.png[] + +=== Hardcoded audience + +When your service relies on realm roles or does not rely on the token's roles at all, a hardcoded audience can be useful. +A hardcoded audience is a protocol mapper that adds the client ID of the specified service client to the token as an audience. +If you want to use a different audience than the client ID, you can use any custom value, such as a URL. + +The protocol mapper can be added directly to the frontend client. +When the protocol mapper is directly added, the audience is always added as well. + +For better control over the protocol mapper, you can create the protocol mapper on the dedicated client scope: + +1. Go to the *Client Scopes* section in the left-side bar. +2. Enter the name for the client scope. +3. Click the *Save* button. ++ +.adding a Client Scope in Keycloak +image::images/keycloak_client_scope_1.png[] + +For create the mapper itself follow the nexts steps: + +1. Go to the Mappers tab. +2. Click the Create button. ++ +.adding a mapper to a Client Scope in Keycloak +image::images/keycloak_client_scope_2.png[] + +In the next screen configure the Mapper as follows: + +1. Enter the name of the mapper. +2. In the Mapper type select `Audience` +3. Click the *Save* button. ++ +.adding a mapper to a Client Scope in Keycloak +image::images/keycloak_client_scope_3.png[] + +=== Keycloak Sample + +This template allows you to understand the *authentication* and *authorization* process using Keycloak: + +* *Authentication*: Is the process of confirming that someone or something is who they claim to be. +To secure access to an application or its data, most technology systems employ some form of authentication. +When you need to access an online site or service, for example, you usually have to enter your username and password. +Then, in the background, it compares the username and password you entered to a record in its database. +If the information you provided matches, the system considers you a valid user and grants you access. + +* *Authorization*: Is the security process that determines a user or service's level of access. In technology, we use authorization to give users or services permission to access some data or perform a particular action. Authentication verifies the user (Lucia) before allowing them access, and authorization determines what they can do once the system has granted them access (view sales information, for example). + +In the `Download` section you will find a sample that you can use as a template for integrating Keycloak in your application. + +NOTE: Please download the template so you can follow the guide successfully. + +The template shows an example of a School with two types of entities, `Student` and `Teacher`, the teachers also have the Administrator role, that allows to access to their `Student list`. + +In the application you will be able to authenticate yourself through a username and password, and this will give you an authorization token that will allow you to use the application with a certain role. + +==== Keycloak Setup + +To setup the keycloak server we provide the `realm_export.json` file that is the configuration of the server that we need to use the template. + +For import the Realm follow the steps below: + +image:images/keycloak_import_realm.png[] + +.Import a realm in keycloak +image::images/keycloak_import_realm_2.png[] + +1. Create a new Realm (1) +2. Click in the *Select file* button and choose the `realm_export.json` file (2) +3. Enter a name for your Realm and click the *Create* button. + +The next step is to create users in your realm for that follow the next steps: + +1. Navigate to the *Users* section (1) in the left-side bar, then the *Add user* button (2): ++ +.Add a user in Keycloak +image::images/keycloak_user_5.png[] + +2. Complete the fields (1) and click the *Save* button (2): ++ +.Add a user in Keycloak +image::images/keycloak_user_6.png[] + +3. Set a password for the user: ++ +.Set credentials to a user in Keycloak +image::images/keycloak_user_7.png[] ++ +- Navigate to the *Credentials* tab (1). +- Enter a password (2). +- Confirm the password (3). +- (*Optional*) +Change the switch to on if you want the user to change their password after the first login (4). +- Click the *Set Password* button to confirm the changes (5). + +For this example, we created two user types,`student` and `teacher`: + +.Users for the template +image::images/keycloak_user_8.png[] + +Now we are going to assign to the user teacher, the `Administrator` Role, for that follow the nexts steps: + +Navigate to the *Users* section (1) and select the correct user to asign the role, select the *Role Mappings* tab (2), in the *Client Roles* section select the `SchoolApplication` Client (3), select the Administrator Role (4) and click the *Add selected* button (5) + +.adding a Client Role to a user in Keycloak +image::images/keycloak_role_7.png[] + +NOTE: If you need more information about how to configure the Keycloak server please refer to the `How to: Configure Keycloak server` section. + + +==== Devon4net.Application.Keycloak + +This is the startup project of the template. Its main purpose is to launch the api and configure it using the settings files. The following figure shows the directory tree of the application: + +.Devon4net.Application.Keycloak Directory tree +image::images/keycloak_application_directory.png[] + +* *Controllers*: This template, has two controllers: the `KeycloakController` for obtaining the access token and the `SchoolController` for testing that token and the user roles. + +* *Model*: The model objects of the application. This template is about a School so we have Persons that are also Students or Teachers. The Teachers will have the `Administrator` role aswell. + +===== Configuration + +The configuration is done in the `appsettings.json` file. It can contain subversions following the structure `appsettings.{environment}.json`. For the keycloak sample, the configuration is done as follows: + +[source, json] +---- +{ + "Keycloak": { + "Realm": "MyRealm", + "Url": "http://localhost:8080/", + "ClientId": "SchoolApplication", + "GrantType": "password" + } +} +---- + +* `Realm`: Your Keycloak realm's name. +* `Url`: The direction of your Keycloak server. +* `ClientId`: The Id of the Client that you created in the Keykloak server administrator console. +* `GrantType`: The grant type used to obtain the token. + +===== Controllers + +====== `KeycloakController` + +It only has one method with the `AllowAnonymous` annotation, that means that this method doesn't need authorization. + +[source, c#] +---- + [HttpGet] + [AllowAnonymous] + public async Task Login(string username, string password) + { + return Ok(await _keycloakService.GetToken(username, password).ConfigureAwait(false)); + } +---- + +The `Login` method calls the Keycloak Service to retrieve the token, it has two parameters, the username and the password. + +.Keycloak Controller +image::images/keycloak_access_token.png[] + +====== `SchoolController` + +Once we have the access token we can use the methods of this controller, for that we have to authorize ourselves: + +image:images/keycloak_authorize_1.png[] + +.Authorization with the access token +image::images/keycloak_authorize_2.png[] + +There are two methods available for this controller: + +* `GetStudentSubjects()`: For this method, the user should be authorized; either students or teachers can use it. + +* `GetTeacherStudents()`: This method access is restricted to teachers only, as indicated by the following policy: ++ +[source, c#] +---- +[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme, Policy = "SchoolPolicy")] +---- ++ +This policy specifies that only teachers with the `Administrator` role are permitted to use this method. + +==== Devon4Net.Application.Keycloak.Implementation + +This package contains all the implementation classes. You will find the following directory tree: + +.Package directory tree +image::images/keycloak_implementation_tree.png[] + +We have organized the files as if it was a Devon4Net module package: + +* Configuration: Contains all the files necesary for configuration. You can use realm-export.json to import the keycloak configuration for this specific example. ++ +You will find in the KeycloakConfiguration class how you can add the different policies and the authorization and authentication configuration. ++ +For example you can use the following code to add a policy that requires the claim user_roles as Administrator: ++ +[source, c#] +---- +services.AddAuthorization(options => + { + options.AddPolicy("SchoolPolicy", policy => policy.RequireClaim("user_roles", "Administrator")); + }); +---- + +* Model: Contains the model objects. In this case we only need the token, which is the response of keycloak but we could put here also the user, for example, if we were to retrieve the information from keycloak. + +* Options: This directory contains the model for all the options used to configure. + +* Services: This directory contains all the services. There is only one service, which access keycloak through the end-points available. ++ +In this example we only need the token, so there is a method accessing the token end-point from keycloak. You can see the end-points available in keycloak in its dashboard. + +=== Downloads + +* link:resources/samples/keycloak/Keycloak.zip[Keycloak Sample] + +=== References + +* https://www.keycloak.org/getting-started/getting-started-docker[Getting Started (Docker) - Keycloak Docs] + +== How to: Avoid cross-site request forgery (XSRF or CSRF) attacks +Every time you authenticate into a web app, your browser becomes trusted for an amount of time to that specific site. This way you can use the application without having to authenticate yourself each time you want to do an operation that requires authorization. This is achieved normally by providing authentication tokens that last a determinate amount of time. + +Your browser includes in each request a token issued by the app at the moment of authentication, the app verifies it and then sends back the response. A cross-site request forgery is a type of attack where a malicious site can use your authentication token to issue requests through your browser. + +This is done, without you even noticing and it works because browser requests automatically include all session cookies. So if the request is done from another site with all these cookies (including your authentication cookie) it wont be different from you actually doing the request. + +For example, you enter the site `vulnerable-bank.com` and forget to log out after doing all of your operations. Now you are surfing the net and enter the site `malicious-site.com` this site has a hidden script that performs the following request: + +[source] +---- +POST /transaction HTTP/1.1 +Host: vulnerable-bank.com +Content-Type: application/x-www-form-urlencoded +Cookie: SessionID = 1n4j0sd7uohpf13j98nh570923c48u + +account={MaliciousAccount} +amount=1000 +---- + +As all the session cookies are included in the request, the site will be allowed to process the transaction without you even noticing. + +The most common way to prevent this vulnerability is by making use of anti forgery tokens. This token is placed in the headers and is issued with the request. The malicious-site cannot + +=== Configuration +To configure Anti-Forgery protection in a devon4net project, you must set `UseXsrf` property in `devonfw` configuration section to true. You will find this section in `appsettings.json`: + +[source, json] +---- +{ + "devonfw": { + "UseXsrf": true + } +} +---- + +Setting this property to true will allow you to use https://docs.microsoft.com/es-es/dotnet/api/microsoft.aspnetcore.antiforgery.iantiforgery?view=aspnetcore-6.0[`IAntiforgery`] interface through the service provider and dependency injection in your project. + +=== Use +In the devon4net Web API Templaate you will be able to find an example of controller using this protection. You can inject the `IAntiforgery` interface in the controller constructor like so: + +[source, c#] +---- +private readonly IAntiforgery _antiForgeryToken; + +public AntiForgeryTokenController(IAntiforgery antiForgeryToken) +{ + _antiForgeryToken = antiForgeryToken; +} +---- + +Now you can access its methods to manage this special token. For creating one we can use `GetAndStoreTokens(HttpContext httpContext)` method available on `IAntiforgery`, and store it in the cookies as shown below: + +[source, c#] +---- +var token = _antiForgeryToken.GetAndStoreTokens(HttpContext); +HttpContext.Response.Cookies.Append(CustomMiddlewareHeaderTypeConst.XsrfToken, token.RequestToken); +---- + +NOTE: Visit the documentation about this interface to find more information about `IAntiforgery` methods. + +This will be done through a GET request. Now we can vaklidate this token in a controller thanks to the attribute `[ValidateAntiForgeryToken]`: + +[source, c#] +---- +[HttpGet] +[Route("/v1/antiforgeryToken/hellosecured")] +[ValidateAntiForgeryToken] +public ActionResult HelloSecured() +{ + return Ok("You have reached a secured AntiForgeryToken method!"); +} +---- + +=== Testing +We will be using https://www.postman.com/[Postman] to test the use of the controller, as you can see in the next figure, if we try to access the end-point protected by the antiforgery token validation we get an error: + +.HelloSecured end-point error +image::images/anti_forgery_hellosecure_error.png[] + +That is beacuse no valid token in `XSRF-TOKEN` header is specified. Lets access the end-point we created to provide an XSRF token: + +.Get XSRF token end-point +image::images/anti_forgery_token.png[] + +Now that we have the token we can specify it in the request header as shown in the next figure: + +.HelloSecured end-point access +image::images/anti_forgery_hellosecure_xsrf.png[] + +=== References +Here are some interesting references to continue learning about this topic: + +* https://owasp.org/www-community/attacks/csrf[Cross Site Request Forgery (CSRF) - Owasp] + +* https://cheatsheetseries.owasp.org/cheatsheets/Cross-Site_Request_Forgery_Prevention_Cheat_Sheet.html[Cross Site Request Forgery Prevention Cheat Sheet - Owasp] + +* https://docs.microsoft.com/en-us/aspnet/core/security/anti-request-forgery?view=aspnetcore-6.0[Prevent Cross-Site Request Forgery (XSRF/CSRF) attacks in ASP.NET Core - Microsoft Docs] + +* https://docs.microsoft.com/es-es/dotnet/api/microsoft.aspnetcore.antiforgery.iantiforgery?view=aspnetcore-6.0[IAntiforgery Interface - Microsoft Docs] + +== How to: Import a database +In this part of the document you will learn how to easily import a database to your devon4net project or any .Net project. This process is known by a variety of different names: scaffolding, database first, reverse engineering... But they all refer to the process of creating entity models and/or database context automatically based on a database schema. + +=== Prerequisites +You can import a database in your favourite type of schema, but for this example we will be using SQL Server and Visual Studio 2022. + +NOTE: Ensure that you have a connection ready to your database and a correct installation of Visual Studio 2022. + +For this example we used https://docs.microsoft.com/es-es/sql/ssms/download-sql-server-management-studio-ssms?view=sql-server-ver15[Microsoft SQL Server Management Studio] to create our database and provide us with a local database connection. + +=== NuGet packages installation +Before starting with the scaffolding you will need to install the following NuGet packages in your destination project. + +==== Open the Package Manager Console + +To open the Package Manager Console, follow the next menu steps: `View > Other Windows > Package Manager Console` and then ensure that the default project in the console is set to the destination project as shown in the next figure. + +NOTE: If the destination project is not the same as the startup project, you may need to install some of the packages in the startup project too. The package manager console will warn you of that if it is necessary. + +.Package Manager Console default project +image::images/pacakge_manager_console.png[] + +==== Install the packages + +* Microsoft.EntityFrameworkCore.Tools + +[source, console] +---- +install-package Microsoft.EntityFrameworkCore.Tools +---- + +* Microsoft.EntityFrameworkCore.Design + +[source, console] +---- +install-package Microsoft.EntityFrameworkCore.Design +---- + +* MIcrosoft.EntityFrameworkCore.SqlServer ++ +NOTE: As we mentioned we will be using a SQL Server schema, we are installing the database provider for it. Please choose your own https://docs.microsoft.com/en-us/ef/core/providers/?tabs=dotnet-core-cli[Database Provider]. ++ +[source, console] +---- +install-package Microsoft.EntityFrameworkCore.SqlServer +---- + +=== Scaffolding command + +Run the following command to execute the scaffolding operation: + +[source, console] +---- +scaffold-dbcontext 'Server=(localdb)\mssqllocaldb;Database=DevonDatabase;' Microsoft.EntityFrameworkCore.SqlServer -Tables School,Teacher -ContextDir Domain\Database -OutputDir Domain\Entities +---- + +NOTE: Your connection string and database provider may be different. + +* The first argument is the connection string. +* The second argument is the Database Provider package for the used schema. +* `-Tables {Table list separated by comma}` is the list of the tables you want to scaffold. +* `-ContextDir` will specify the relative path for the context. +* `-OutputDir` will specify the relative path for the models. + +In our case, before doing the scaffolding we had something like this: + +.Directory tree before scaffolding +image::images/before_scaffolding.png[] + +And the scaffolding produced the following directory tree: + +.Directory tree after scaffolding +image::images/after_scaffolding.png[] + +If you do not specify `-Tables`, `-ContextDir` and `-OutputDir` all of the tables will be scaffolded and the default directories will be the project directory. + +=== Add the context for Dependency Injection +Now that we have our context we will need to add it either in `Program.cs` or `SetupDatabase` method in `DevonConfiguration` class. + +As we are using Devon, we will need to go to `Devon4Net.Application.WebAPI.Implementation.Configuration.DevonConfiguration` and add the folowing line in `SetupDatabase` method: + +[source, c#] +---- +services.SetupDatabase(configuration,"DevonDatabase", DatabaseType.SqlServer).ConfigureAwait(false); +---- + +Where: + +|=== +|*Parameter* |*Description* +|`` | Database context you want to add +|`configuration` | Available `IConfiguration` instance +|`"DevonDatabase"` | Name of the connection string defined at `ConnectionString` section in the `appsettings.{environment}.json` configuration file +|`DatabaseType` | Database schema available in devon (see the following list). +|=== + +List of supported databases: + +* SqlServer +* Sqlite +* InMemory +* Cosmos +* PostgreSQL +* MySql +* MariaDb +* FireBird +* Oracle +* MSAccess + +=== References + +* https://docs.microsoft.com/en-us/ef/core/managing-schemas/scaffolding?tabs=vs[Reverse Engineering - Microsoft Docs] + +* https://docs.microsoft.com/en-us/ef/core/providers/?tabs=dotnet-core-cli[Database Providers - Microsoft Docs] + + +== How to: Use LiteDb + +In this part you will learn how to easily start using a LiteDb database in your project. + +NOTE: Please read the documentation of this component to learn more about how to set it up and use it. + +=== Video + +As you will find all the information in the component documentation, we prepared a video using LiteDb in a very short example: + +.How to setup and use LiteDb component +video::videos/howto_litedb.mp4[] + +== How to: Customize Headers + +HTTP headers let the client and the server provide additional information with an HTTP request or a response. As this headers provide information about either the client or the server, it can be dangerous if this information lands in the wrong hands. + +As Owasp explains in great detail, proper HTTP headers can help prevent security vulnerabilities like Cross-Site Scripting, Clickjacking, Information disclosure and more. + +In devon we take security very seriously, that's why we developed a very easy form of customizing HTTP headers. You will be able to do it configuring the headers in the `appsettings.{environment}.json` file. A middleware will be configured with those options and will modify each HTTP response according to the specified options. + +=== Configuration + +[source, json] +---- +"Headers": { + "AccessControlExposeHeader": "Authorization", + "StrictTransportSecurityHeader": "", + "XFrameOptionsHeader": "DENY", + "XssProtectionHeader": "1;mode=block", + "XContentTypeOptionsHeader": "nosniff", + "ContentSecurityPolicyHeader": "", + "PermittedCrossDomainPoliciesHeader": "", + "ReferrerPolicyHeader": "" + }, +---- + +The following table shows the options that can be configured. + +NOTE: Please refer to the links provided to learn more about each header and what can be done with it. + +|==== +|*Option* |*Header* |*Description* +|`AccessControlExposeHeader` |https://developer.mozilla.org/es/docs/Web/HTTP/Headers/Access-Control-Expose-Headers[`Access-Control-Expose-Headers`] |Indicates which headers may be exposed as part of the response by listing their names. +|`StrictTransportSecurityHeader` |https://developer.mozilla.org/es/docs/Web/HTTP/Headers/Strict-Transport-Security[`Strict-Transport-Security`] |Allows a website to tell browsers that it should only communicate with HTTPS instead of using HTTP. +|`XFrameOptionsHeader` |https://developer.mozilla.org/es/docs/Web/HTTP/Headers/X-Frame-Options[`X-Frame-Options`] | Can be used to indicate whether a browser should be allowed to render a page in a ``, `