forked from gongxuegit/tiku-backend.net
feat: harden SaaS authentication and authorization
This commit is contained in:
@@ -3,6 +3,7 @@ using System.Security.Cryptography;
|
||||
using System.Text.Json;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Tiku.Application.Growth;
|
||||
using Tiku.Application.Security;
|
||||
using Tiku.Domain.Commerce;
|
||||
using Tiku.Domain.Common;
|
||||
using Tiku.Domain.Growth;
|
||||
@@ -14,7 +15,8 @@ namespace Tiku.Infrastructure.Growth;
|
||||
|
||||
public sealed class ReferralService(
|
||||
TikuDbContext dbContext,
|
||||
IReferralQrcodeGenerator qrcodeGenerator) : IReferralService
|
||||
IReferralQrcodeGenerator qrcodeGenerator,
|
||||
ICurrentAccessContext currentAccessContext) : IReferralService
|
||||
{
|
||||
private static readonly HashSet<string> AllowedEventTypes = new(StringComparer.OrdinalIgnoreCase)
|
||||
{
|
||||
@@ -109,7 +111,7 @@ public sealed class ReferralService(
|
||||
referralCode.UserId,
|
||||
membership.Role,
|
||||
user.Name,
|
||||
user.Username,
|
||||
user.UserName,
|
||||
user.Phone
|
||||
})
|
||||
.FirstOrDefaultAsync(cancellationToken);
|
||||
@@ -121,7 +123,7 @@ public sealed class ReferralService(
|
||||
row.UserId,
|
||||
row.Code,
|
||||
row.Role.ToString(),
|
||||
FirstNonBlank(row.Name, row.Username, row.Phone));
|
||||
FirstNonBlank(row.Name, row.UserName, row.Phone));
|
||||
}
|
||||
|
||||
public async Task<ReferralTrackResult> TrackEventAsync(
|
||||
@@ -655,16 +657,11 @@ public sealed class ReferralService(
|
||||
|
||||
private async Task AssertAdminAsync(ReferralAdminActor actor, CancellationToken cancellationToken)
|
||||
{
|
||||
var isAdmin = await dbContext.TenantMemberships.AnyAsync(
|
||||
item =>
|
||||
item.TenantId == actor.TenantId &&
|
||||
item.UserId == actor.UserId &&
|
||||
item.Status == MembershipStatus.Active &&
|
||||
(item.Role == TenantRole.PlatformAdmin ||
|
||||
item.Role == TenantRole.TenantOwner ||
|
||||
item.Role == TenantRole.TenantAdmin),
|
||||
cancellationToken);
|
||||
if (!isAdmin)
|
||||
var access = await currentAccessContext.GetAsync(cancellationToken);
|
||||
if (!access.IsCurrentTenantMember ||
|
||||
access.TenantId != actor.TenantId ||
|
||||
access.UserId != actor.UserId ||
|
||||
!access.HasTenantPermission(BackendPermissions.TenantCrmManage))
|
||||
{
|
||||
throw new ReferralException("Referral admin access was denied.", "referral_access_denied");
|
||||
}
|
||||
@@ -677,7 +674,7 @@ public sealed class ReferralService(
|
||||
{
|
||||
var user = await dbContext.Users.AsNoTracking()
|
||||
.Where(item => item.Id == referrerUserId)
|
||||
.Select(item => new { item.Name, item.Username, item.Phone })
|
||||
.Select(item => new { item.Name, item.UserName, item.Phone })
|
||||
.FirstOrDefaultAsync(cancellationToken);
|
||||
var membership = await dbContext.TenantMemberships.AsNoTracking()
|
||||
.Where(item => item.TenantId == tenantId && item.UserId == referrerUserId)
|
||||
@@ -714,7 +711,7 @@ public sealed class ReferralService(
|
||||
|
||||
return new ReferralStatsItem(
|
||||
referrerUserId,
|
||||
FirstNonBlank(user?.Name, user?.Username, user?.Phone),
|
||||
FirstNonBlank(user?.Name, user?.UserName, user?.Phone),
|
||||
membership.ToString(),
|
||||
inviteCode,
|
||||
leads.Length,
|
||||
|
||||
Reference in New Issue
Block a user