Blazor - Créer un utilisateur Root au démarrage de l'application
Tags: csharp, blazor, dotnet, tutorial
Published: 2020-10-22 07:41:44

J'aime bien créer un utilisateur "root" qui a le rôle "admin" dans l'application. Dans cet article, je vais vous expliquer comment faire. J'utilise une base de données SQLite, mais cela fonctionne avec toutes les bases de données, tant qu'on utilise EntityFramework.

Commençons par la class Startup.cs, dans la méthode ConfigureServices, il faut vérifier et ajouter si besoin, les lignes suivantes :

```csharp
services.AddDbContext<ApplicationDbContext>(options =>        
options.UseSqlite(Configuration.GetConnectionString("DefaultConnection")));

services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = true)
                .AddRoles<IdentityRole>() // <--- Important
                .AddEntityFrameworkStores<ApplicationDbContext>();
```
Ces lignes permettent d'ajouter la connexion à SQLite avec la configuration du nom de DefaultConnection. Le "AddRoles" nous permettra d'appeler IdentityRole.

Voici le DefaultConnection
```
"ConnectionStrings": {
    "DefaultConnection": "DataSource=database/app.db"
```
Le fichier de base de données sera dans un répertoire database. Ce répertoire sera créé au lancement de l'application.
**Attention** : Quand vous serez dans une session debug, le répertoire sera créé dans votre solution, là où se trouve le code source, pas dans le répertoire bin\debug... Quand l'application sera déployée ce répertoire sera créé là se trouve les binaires.

Ensuite, il faut créer une `class static DataInitializer` et ajouter cette propriété et cette méthode :
```csharp
//NOTE : Mettre les noms des rôles que vous voulez.
private static readonly string[] Roles = new string[] { "Admin", "Manager", "Member" };

public static async Task InitData(RoleManager<IdentityRole> roleManager, UserManager<IdentityUser> userManager)
{

	foreach (var role in Roles)
	{
		if (!await roleManager.RoleExistsAsync(role))
		{
			await roleManager.CreateAsync(new IdentityRole(role));
		}
	}
	// Création de l'utilisateur Root.
	var user = await userManager.FindByNameAsync("root@email.com");
	if (user == null)
	{
		var poweruser = new IdentityUser
		{
			UserName = "root@email.com",
			Email = "root@email.com",
			EmailConfirmed = true
		};
		string userPwd = "Azerty123!";
		var createPowerUser = await userManager.CreateAsync(poweruser, userPwd);
		if (createPowerUser.Succeeded)
		{
			await userManager.AddToRoleAsync(poweruser, "Admin");
		}
	}
}
```
Cette méthode permet d'ajouter les rôles voulus, de créer l'utilisateur root, et de lui mettre le rôle Admin.

Ensuite, il faut appeler cette méthode au démarrage de l'application, donc dans le Main de la Class Program.cs

```csharp
public static void Main(string[] args)
{
    var host = CreateHostBuilder(args).Build();

    // Création du répertoire pour la base de données
    string pathDatabase = Path.Combine(AppContext.BaseDirectory, "database");
    if(!Directory.Exists(pathDatabase))
        Directory.CreateDirectory(pathDatabase);

    var scopeFactory = host.Services.GetRequiredService<IServiceScopeFactory>();
    using (var scope = scopeFactory.CreateScope())
    {
        var db = scope.ServiceProvider.GetRequiredService<ApplicationDbContext>();
        var roleManager = scope.ServiceProvider.GetRequiredService<RoleManager<IdentityRole>>();
        var userManager = scope.ServiceProvider.GetRequiredService<UserManager<IdentityUser>>();

        // Vrai si la base de données est créée, false si elle existait déjà.
        if (db.Database.EnsureCreated())
        {
            DataInitializer.InitData(roleManager, userManager).Wait();
        }
    }

    host.Run();
}
```
Au lancement de l'application, un Scope est créé pour pouvoir récupérer les services IdentityRole, ApplicationDbContext et IdentityUser. Une vérification que la base de données est créée, si le fichier n'existe pas, il sera créé automatiquement. L'appel à `DataInitializer.InitData` pour la création de notre utilisateur "root".

Voilà, vous pouvez retrouver le code source sur [GitHub](https://github.com/AnthonyRyck/CodesPourDevTo/tree/master/src/SQLiteWithRoot).