Skip to content

Commit

Permalink
Updated ITenantChangeService for version 3 - see #14
Browse files Browse the repository at this point in the history
  • Loading branch information
JonPSmith committed Mar 15, 2022
1 parent ac2951f commit d092a7b
Show file tree
Hide file tree
Showing 22 changed files with 400 additions and 387 deletions.
6 changes: 3 additions & 3 deletions AuthPermissions/AdminCode/IAuthTenantAdminService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ public interface IAuthTenantAdminService
/// This updates the name of this tenant to the <see param="newTenantLevelName"/>.
/// This also means all the children underneath need to have their full name updated too
/// This method uses the <see cref="ITenantChangeService"/> you provided via the <see cref="RegisterExtensions.RegisterTenantChangeService{TTenantChangeService}"/>
/// to update the application's tenant data. You also need to set the <see cref="AuthPermissionsOptions.AppConnectionString"/> in the options.
/// to update the application's tenant data.
/// </summary>
/// <param name="tenantId">Primary key of the tenant to change</param>
/// <param name="newTenantName">This is the new name for this tenant name</param>
Expand All @@ -86,7 +86,7 @@ public interface IAuthTenantAdminService
/// This moves a hierarchical tenant to a new parent (which might be null). This changes the TenantFullName and the
/// TenantDataKey of the selected tenant and all of its children
/// This method uses the <see cref="ITenantChangeService"/> you provided via the <see cref="RegisterExtensions.RegisterTenantChangeService{TTenantChangeService}"/>
/// to move the application's tenant data. You also need to set the <see cref="AuthPermissionsOptions.AppConnectionString"/> in the options.
/// to move the application's tenant data.
/// </summary>
/// <param name="tenantToMoveId">The primary key of the AuthP tenant to move</param>
/// <param name="newParentTenantId">Primary key of the new parent, if 0 then you move the tenant to top</param>
Expand All @@ -97,7 +97,7 @@ public interface IAuthTenantAdminService
/// This will delete the tenant (and all its children if the data is hierarchical) and uses the <see cref="ITenantChangeService"/>,
/// but only if no AuthP user are linked to this tenant (it will return errors listing all the AuthP user that are linked to this tenant
/// This method uses the <see cref="ITenantChangeService"/> you provided via the <see cref="RegisterExtensions.RegisterTenantChangeService{TTenantChangeService}"/>
/// to delete the application's tenant data. You also need to set the <see cref="AuthPermissionsOptions.AppConnectionString"/> in the options.
/// to delete the application's tenant data.
/// </summary>
/// <returns>Status returning the <see cref="ITenantChangeService"/> service, in case you want copy the delete data instead of deleting</returns>
Task<IStatusGeneric<ITenantChangeService>> DeleteTenantAsync(int tenantId);
Expand Down
77 changes: 43 additions & 34 deletions AuthPermissions/AdminCode/ITenantChangeService.cs
Original file line number Diff line number Diff line change
@@ -1,60 +1,73 @@
// Copyright (c) 2021 Jon P Smith, GitHub: JonPSmith, web: http://www.thereformedprogrammer.net/
// Licensed under MIT license. See License.txt in the project root for license information.

using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.Data.SqlClient;
using Microsoft.EntityFrameworkCore;
using AuthPermissions.AdminCode.Services;
using AuthPermissions.DataLayer.Classes;

namespace AuthPermissions.AdminCode
{
/// <summary>
/// This is the interface for the creating, deleting, updating, or hierarchical moving of tenants
/// This allows the changes to the AuthP's Tenant to be applied to the application's tenant data within a transaction.
/// This means if either the AuthP's Tenant, or the application's tenant data fails, then both changes will be rolled back
/// This service should apply changes to the application's database.
/// The methods are called by the <see cref="AuthTenantAdminService"/> methods withing a transaction,
/// so that if the application database changes fails, then the AuthP changes will be rolled back.
/// </summary>
public interface ITenantChangeService
{
/// <summary>
/// This creates an instance of the application's DbContext to use within an transaction with the AuthPermissionsDbContext
/// </summary>
DbContext GetNewInstanceOfAppContext(SqlConnection sqlConnection);

/// <summary>
/// When a new AuthP Tenant is created, then this method is called. If you have a tenant-type entity in your
/// application's database, then this allows you to create a new entity for the new tenant
/// application's database, then this allows you to create a new entity for the new tenant.
/// You should apply multiple changes within a transaction so that if any fails then any previous changes will be rolled back.
/// NOTE: With hierarchical tenants you cannot be sure that the tenant has, or will have, children
/// </summary>
/// <param name="appTransactionContext">The application's DbContext within a transaction</param>
/// <param name="dataKey">The DataKey of the tenant being deleted</param>
/// <param name="tenantId">The TenantId of the tenant being deleted</param>
/// <param name="fullTenantName">The full name of the tenant being deleted</param>
/// <returns>Returns null if all OK, otherwise the create is rolled back and the return string is shown to the user</returns>
Task<string> CreateNewTenantAsync(DbContext appTransactionContext, string dataKey, int tenantId, string fullTenantName);
Task<string> CreateNewTenantAsync(string dataKey, int tenantId, string fullTenantName);

/// <summary>
/// This is called when the name of your Tenants is changed. This is useful if you use the tenant name in your multi-tenant data.
/// NOTE: The created application's DbContext won't have a DataKey, so you will need to use IgnoreQueryFilters on any EF Core read.
/// You should apply multiple changes within a transaction so that if any fails then any previous changes will be rolled back.
/// </summary>
/// <param name="dataKey">The DataKey of the tenant</param>
/// <param name="tenantId">The TenantId of the tenant</param>
/// <param name="fullTenantName">The full name of the tenant</param>
/// <returns>Returns null if all OK, otherwise the name change is rolled back and the return string is shown to the user</returns>
Task<string> HandleUpdateNameAsync(string dataKey, int tenantId, string fullTenantName);

/// <summary>
/// This is called within a transaction to allow the the application-side of the database to either
/// a) delete all the application-side data with the given DataKey, or b) list the changes to show to the admin user
/// This is used with single-level tenant to either
/// a) delete all the application-side data with the given DataKey, or
/// b) soft-delete the data.
/// You should apply multiple changes within a transaction so that if any fails then any previous changes will be rolled back
/// Notes:
/// - The created application's DbContext won't have a DataKey, so you will need to use IgnoreQueryFilters on any EF Core read
/// - When working in an hierarchical tenants you can get multiple calls, starting with the lower levels first
/// - You can provide information of what you have done by adding public parameters to this class.
/// The TenantAdmin <see cref="AuthTenantAdminService.DeleteTenantAsync"/> method returns your class on a successful Delete
/// </summary>
/// <param name="appTransactionContext">The application's DbContext within a transaction</param>
/// <param name="dataKey">The DataKey of the tenant being deleted</param>
/// <param name="tenantId">The TenantId of the tenant being deleted</param>
/// <param name="fullTenantName">The full name of the tenant being deleted</param>
/// <returns>Returns null if all OK, otherwise the delete is rolled back and the return string is shown to the user</returns>
Task<string> HandleTenantDeleteAsync(DbContext appTransactionContext, string dataKey, int tenantId, string fullTenantName);
/// <returns>Returns null if all OK, otherwise the AuthP part of the delete is rolled back and the return string is shown to the user</returns>
Task<string> SingleTenantDeleteAsync(string dataKey, int tenantId, string fullTenantName);

/// <summary>
/// This is called when the name of your Tenants is changed. This is useful if you use the tenant name in your multi-tenant data.
/// NOTE: The created application's DbContext won't have a DataKey, so you will need to use IgnoreQueryFilters on any EF Core read
/// This is used with hierarchical tenants to either
/// a) delete all the application-side data with the given DataKey, or
/// b) soft-delete the data.
/// You should apply multiple changes within a transaction so that if any fails then any previous changes will be rolled back
/// Notes:
/// - The created application's DbContext won't have a DataKey, so you will need to use IgnoreQueryFilters on any EF Core read
/// - You can provide information of what you have done by adding public parameters to this class.
/// The TenantAdmin <see cref="AuthTenantAdminService.DeleteTenantAsync"/> method returns your class on a successful Delete
/// </summary>
/// <param name="appTransactionContext">The application's DbContext within a transaction</param>
/// <param name="dataKey">The DataKey of the tenant</param>
/// <param name="tenantId">The TenantId of the tenant</param>
/// <param name="fullTenantName">The full name of the tenant</param>
/// <returns>Returns null if all OK, otherwise the name change is rolled back and the return string is shown to the user</returns>
Task<string> HandleUpdateNameAsync(DbContext appTransactionContext, string dataKey, int tenantId, string fullTenantName);
/// <param name="tenantsInOrder">The tenants to delete with the children first in case a higher level links to a lower level</param>
/// <returns>Returns null if all OK, otherwise the AuthP part of the delete is rolled back and the return string is shown to the user</returns>
Task<string> HierarchicalTenantDeleteAsync(List<Tenant> tenantsInOrder);

/// <summary>
/// This is used with hierarchical tenants, where you move one tenant (and its children) to another tenant
Expand All @@ -64,14 +77,10 @@ public interface ITenantChangeService
/// - The created application's DbContext won't have a DataKey, so you will need to use IgnoreQueryFilters on any EF Core read
/// - You can get multiple calls if move a higher level
/// </summary>
/// <param name="appTransactionContext"></param>
/// <param name="oldDataKey">The old DataKey to look for</param>
/// <param name="newDataKey">The new DataKey to change to</param>
/// <param name="tenantId">The TenantId of the tenant being moved</param>
/// <param name="newFullTenantName">The new full name of the tenant</param>
/// <returns>Returns null if all OK, otherwise the move is rolled back and the return string is shown to the user</returns>
Task<string> MoveHierarchicalTenantDataAsync(DbContext appTransactionContext, string oldDataKey, string newDataKey,
int tenantId, string newFullTenantName);
/// <param name="tenantToUpdate">The data to update each tenant. This starts at the parent and then recursively works down the children</param>
/// <returns>Returns null if all OK, otherwise AuthP part of the move is rolled back and the return string is shown to the user</returns>
Task<string> MoveHierarchicalTenantDataAsync(
List<(string oldDataKey, string newDataKey, int tenantId, string newFullTenantName)> tenantToUpdate);

}
}
Loading

0 comments on commit d092a7b

Please sign in to comment.