For the Addin Users Project you need to following reference:
using LemonEdge.API.Client.CommonUI;
using LemonEdge.ClientDB.Host;
using LemonEdge.Examples.ConnectingToLemonEdge;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Worker = LemonEdge.Examples.AddingUsers.Worker;
Similar to the Connecting To LemonEdge, The host and services need to be configured. The host is configured using the following.
try
{
var host = Host.CreateDefaultBuilder(args).ConfigureServices(ConfigureServices).Build();
host.Services.InitialiseLemonEdge();
await host.RunAsync();
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
The services are configured in the ConfigureServices function in the following way similar to the Connecting To LemonEdge project.
void ConfigureServices(HostBuilderContext hostContext, IServiceCollection services)
{
services.ConfigureLemonEdge(hostContext.Configuration);
services.AddScoped<IConnector, Connector>();
services.AddSingleton<IAuthenticationService, AuthenticationService>();
services.AddHostedService<Worker>();
}
These are the refernces need for the class
using LemonEdge.API.Client.CommonUI;
using LemonEdge.API.Core.Context;
using LemonEdge.API.Core.Data;
using LemonEdge.API.Entities.Administration;
using LemonEdge.Examples.ConnectingToLemonEdge;
using LemonEdge.Utils.Database;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
The class needs to inherit BackgroundService.
public class Worker : BackgroundService
The Worker constructor takes the following parameters: connector: The LemonEdge IConnector enabling access to the system. lifetime: The IHostApplicationLifetime needed to manage application lifetime. authenticationService: An example service for authenticating to LemonEdge logger: The logger to output progress.
Properties
private readonly IAuthenticationService _authenticationService;
private readonly IConnector _connector;
private readonly IHostApplicationLifetime _lifetime;
private readonly ILogger<Worker> _logger;
private UserInfo? _user;
Constructor
public Worker(IAuthenticationService authenticationService, IConnector connector, IHostApplicationLifetime lifetime, ILogger<Worker> logger)
{
_authenticationService = authenticationService;
_connector = connector;
_lifetime = lifetime;
_logger = logger;
}
ExecuteAsync logs into the service. Then it creates a context to be able to modify the data. It follows this by creating a user, then assigning them the Admin team and role. Last it attemps to save the changes.
protected override async Task ExecuteAsync(CancellationToken cancelToken)
{
try
{
_user = await _authenticationService.Login();
using var context = await _connector.Create();
// Check if the email is already in use
const string email = "someotheremail@lemonedge.com";
var isExistingUser = await IsExistingUser(context, email);
if (isExistingUser) throw new ArgumentException("A user with the provided email already exists.", email);
// Create a new user
// Note: The password could be randomly generated and then emailed to the user in question rather than stored in plain-text.
var user = await CreateNewUser(context, "Some Other New User", email, "SomeDefaultPassword");
_logger.LogInformation("User created: {email}", user.EmailLogin);
// Find the admin role and team
var adminRole = await GetRole(context, "Admin");
var adminTeam = await GetTeam(context, "Admin");
// Assign user to a role and team
await AssignUserRole(context, adminRole, user);
_logger.LogInformation("Assigned user to the {roleName} role.", adminRole.Name);
await AssignUserTeam(context, adminTeam, user);
_logger.LogInformation("Assigned user to the {teamName} team.", adminTeam.Name);
// Save changes
await context.SaveChanges(cancelToken);
_logger.LogInformation("Changes saved.");
}
catch (Exception ex)
{
_logger.LogError(ex, "An error occurred during user management.");
}
finally
{
_lifetime.StopApplication();
}
}
CreateNewUser is a function that creates a new user using the CreateNewItem function.
private async Task<IUser> CreateNewUser(IEntityUpdaterUI context, string name, string email, string password)
{
// Create a new user
var user = await context.EntityCreator.CreateNewItem<IUser>(_user, context.Cache, context);
user.Name = name;
user.EmailLogin = email;
user.HashedPassword = User.EncryptPassword(user.ID, password);
user.WindowsLoginDomain = "";
return user;
}
IsExistingUser is a function that checks if a user exist by trying to obtain it from the context.
private async Task<bool> IsExistingUser(IEntityUpdaterUI context, string email)
{
var teams = await context.GetItems<IUser>()
.Where(nameof(IUser.EmailLogin), SQLOperator.Equals, email)
.Execute(context);
var adminTeam = teams.FirstOrDefault();
return adminTeam != null;
}
GetRole obtains a role by matching its name to a given string.
private async Task<IRole> GetRole(IEntityUpdaterUI context, string roleName)
{
var roles = await context.GetItems<IRole>()
.Where(nameof(IRole.Name), SQLOperator.Equals, roleName)
.Execute(context);
var adminRole = roles.FirstOrDefault();
if (adminRole == null) throw new ArgumentException("Could not find the specified role.");
return adminRole;
}
GetTeam obtains a team by matching its name to a given string.
private async Task<ITeam> GetTeam(IEntityUpdaterUI context, string teamName)
{
var teams = await context.GetItems<ITeam>()
.Where(nameof(ITeam.Name), SQLOperator.Equals, teamName)
.Execute(context);
var adminTeam = teams.FirstOrDefault();
if (adminTeam == null) throw new ArgumentException("Could not find the specified team.");
return adminTeam;
}
AssignUserRole creates a new IUserRole item which represents the link between a user and a role
private async Task AssignUserRole(IEntityUpdaterUI context, IRole adminRole, IUser user)
{
var userRole = await context.EntityCreator.CreateNewItem<IUserRole>(_user, context.Cache, context);
userRole.RoleID = adminRole.ID;
userRole.UserID = user.ID;
}
AssignUserTeam creates a new IUserTeam item which represents the link between a user and a team
private async Task AssignUserTeam(IEntityUpdaterUI context, ITeam adminTeam, IUser user)
{
var userTeam = await context.EntityCreator.CreateNewItem<IUserTeam>(_user, context.Cache, context);
userTeam.TeamID = adminTeam.ID;
userTeam.UserID = user.ID;
}