Kickuser çalışması
This commit is contained in:
parent
8234b1de2a
commit
6f3b20ffe2
7 changed files with 100 additions and 2 deletions
|
|
@ -7,6 +7,7 @@ using Sozsoft.Platform.Entities;
|
|||
using Sozsoft.Platform.Extensions;
|
||||
using Sozsoft.Platform.Identity.Dto;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using OpenIddict.Abstractions;
|
||||
using Volo.Abp.Application.Services;
|
||||
using Volo.Abp.Domain.Repositories;
|
||||
using Volo.Abp.Guids;
|
||||
|
|
@ -20,6 +21,8 @@ public class PlatformIdentityAppService : ApplicationService
|
|||
{
|
||||
public IIdentityUserAppService IdentityUserAppService { get; }
|
||||
private readonly IIdentityUserRepository identityUserRepository;
|
||||
private readonly IIdentitySessionRepository identitySessionRepository;
|
||||
private readonly IOpenIddictTokenManager openIddictTokenManager;
|
||||
public IRepository<PermissionDefinitionRecord, Guid> permissionRepository { get; }
|
||||
public IRepository<Branch, Guid> branchRepository { get; }
|
||||
public IRepository<BranchUsers, Guid> branchUsersRepository { get; }
|
||||
|
|
@ -31,6 +34,8 @@ public class PlatformIdentityAppService : ApplicationService
|
|||
public PlatformIdentityAppService(
|
||||
IIdentityUserAppService identityUserAppService,
|
||||
IIdentityUserRepository identityUserRepository,
|
||||
IIdentitySessionRepository identitySessionRepository,
|
||||
IOpenIddictTokenManager openIddictTokenManager,
|
||||
IRepository<PermissionDefinitionRecord, Guid> permissionRepository,
|
||||
IRepository<Branch, Guid> branchRepository,
|
||||
IRepository<BranchUsers, Guid> branchUsersRepository,
|
||||
|
|
@ -41,6 +46,8 @@ public class PlatformIdentityAppService : ApplicationService
|
|||
{
|
||||
this.IdentityUserAppService = identityUserAppService;
|
||||
this.identityUserRepository = identityUserRepository;
|
||||
this.identitySessionRepository = identitySessionRepository;
|
||||
this.openIddictTokenManager = openIddictTokenManager;
|
||||
this.workHourRepository = workHourRepository;
|
||||
this.permissionRepository = permissionRepository;
|
||||
this.branchRepository = branchRepository;
|
||||
|
|
@ -231,4 +238,24 @@ public class PlatformIdentityAppService : ApplicationService
|
|||
|
||||
user.Claims.Remove(claim);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Kullanıcıyı anlık olarak oturumdan atar:
|
||||
/// 1. AbpSessions kaydını siler → concurrent lisans slotunu serbest bırakır.
|
||||
/// 2. OpenIddict tokenlarını revoke eder → access token anında geçersiz olur.
|
||||
/// </summary>
|
||||
public async Task KickUserAsync(Guid userId)
|
||||
{
|
||||
using (CurrentTenant.Change(CurrentTenant.Id))
|
||||
{
|
||||
// 1. AbpSessions temizle
|
||||
var sessions = await identitySessionRepository.GetListAsync(userId: userId);
|
||||
foreach (var session in sessions)
|
||||
await identitySessionRepository.DeleteAsync(session);
|
||||
|
||||
// 2. OpenIddict tokenlarını revoke et
|
||||
await foreach (var token in openIddictTokenManager.FindBySubjectAsync(userId.ToString()))
|
||||
await openIddictTokenManager.TryRevokeAsync(token);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1038,6 +1038,12 @@
|
|||
"en": "Hangfire Refresh",
|
||||
"tr": "Hangfire Yenile"
|
||||
},
|
||||
{
|
||||
"resourceName": "Platform",
|
||||
"key": "App.Platform.KickUser",
|
||||
"en": "Kick User",
|
||||
"tr": "Kullanıcıyı At"
|
||||
},
|
||||
{
|
||||
"resourceName": "Platform",
|
||||
"key": "DeleteConfirmation",
|
||||
|
|
@ -3060,6 +3066,12 @@
|
|||
"en": "Redis cache is being cleared.",
|
||||
"tr": "Redis önbelleği temizleniyor."
|
||||
},
|
||||
{
|
||||
"resourceName": "Platform",
|
||||
"key": "App.KickUser.Message",
|
||||
"en": "User is being kicked.",
|
||||
"tr": "Kullanıcı atılıyor."
|
||||
},
|
||||
{
|
||||
"resourceName": "Platform",
|
||||
"key": "LoginEndDate",
|
||||
|
|
|
|||
|
|
@ -2146,6 +2146,16 @@ public class ListFormSeeder_Administration : IDataSeedContributor, ITransientDep
|
|||
ColumnOptionJson = DefaultColumnOptionJson(),
|
||||
PermissionJson = DefaultPermissionJson(listFormName),
|
||||
PagerOptionJson = DefaultPagerOptionJson,
|
||||
CommandColumnJson = JsonSerializer.Serialize(new CommandColumnDto[] {
|
||||
new() {
|
||||
ButtonPosition= UiCommandButtonPositionTypeEnum.CommandColumn,
|
||||
Hint = "App.Platform.KickUser",
|
||||
Text = "App.Platform.KickUser",
|
||||
AuthName=listFormName,
|
||||
OnClick = "UiEvalService.ApiKickUser(e.row.data.UserId, gridRef);",
|
||||
IsVisible = true,
|
||||
},
|
||||
}),
|
||||
}
|
||||
);
|
||||
|
||||
|
|
@ -2172,7 +2182,7 @@ public class ListFormSeeder_Administration : IDataSeedContributor, ITransientDep
|
|||
SourceDbType = DbType.Guid,
|
||||
FieldName = "SessionId",
|
||||
CaptionName = "App.Listform.ListformField.SessionId",
|
||||
Width = 250,
|
||||
Width = 275,
|
||||
ListOrderNo = 2,
|
||||
Visible = true,
|
||||
IsActive = true,
|
||||
|
|
|
|||
|
|
@ -95,6 +95,7 @@ public class PlatformHttpApiHostModule : AbpModule
|
|||
options.AddAudiences(PlatformConsts.AppName);
|
||||
options.UseLocalServer();
|
||||
options.UseAspNetCore();
|
||||
options.EnableTokenEntryValidation();
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ import { generateBackgroundWorkers } from '@/services/background-worker.service'
|
|||
import { getLocalization } from '@/services/localization.service'
|
||||
import { store } from '@/store'
|
||||
import { clearRedisCache } from './languageText.service'
|
||||
import { kickUser } from './identity.service'
|
||||
|
||||
export abstract class UiEvalService {
|
||||
static Init = () => {
|
||||
|
|
@ -84,6 +85,47 @@ export abstract class UiEvalService {
|
|||
},
|
||||
)
|
||||
}
|
||||
|
||||
static ApiKickUser = (userId: string, gridRef?: any) => {
|
||||
// Get store state directly instead of using hook
|
||||
const state = store.getState()
|
||||
const { texts, config } = state.abpConfig
|
||||
|
||||
// Create translate function similar to useLocalization hook
|
||||
const translate = (
|
||||
localizationKey: string,
|
||||
params?: Record<string, string | number>,
|
||||
defaultResourceName?: string,
|
||||
): string => {
|
||||
if (!texts) {
|
||||
return localizationKey
|
||||
}
|
||||
return getLocalization(
|
||||
texts,
|
||||
defaultResourceName ?? config?.localization?.defaultResourceName,
|
||||
localizationKey,
|
||||
params,
|
||||
)
|
||||
}
|
||||
|
||||
const asyncCall = async () => {
|
||||
await kickUser(userId)
|
||||
if (gridRef?.current) {
|
||||
gridRef.current.instance().refresh()
|
||||
}
|
||||
}
|
||||
|
||||
asyncCall()
|
||||
|
||||
toast.push(
|
||||
<Notification type="success" duration={2000}>
|
||||
{translate('::App.KickUser.Message')}
|
||||
</Notification>,
|
||||
{
|
||||
placement: 'top-end',
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
const _global = (window || global) as any
|
||||
|
|
|
|||
|
|
@ -93,3 +93,9 @@ export const deleteClaimUser = (id: string, userId?: string) =>
|
|||
method: 'DELETE',
|
||||
url: `/api/app/platform-identity/${id}/claim-user/${userId}`,
|
||||
})
|
||||
|
||||
export const kickUser = (userId: string) =>
|
||||
apiService.fetchData({
|
||||
method: 'POST',
|
||||
url: `/api/app/platform-identity/kick-user/${userId}`,
|
||||
})
|
||||
|
|
|
|||
|
|
@ -442,8 +442,8 @@ const useListFormColumns = ({
|
|||
|
||||
const item = {
|
||||
visible: visibleFunc,
|
||||
hint: action.hint,
|
||||
icon: action.icon,
|
||||
hint: translate('::' + action.hint),
|
||||
text: translate('::' + action.text),
|
||||
onClick: (e: any) => {
|
||||
if (typeof e.event?.preventDefault === 'function') {
|
||||
|
|
|
|||
Loading…
Reference in a new issue