SUPPORT-8956: use domain_id from token

This commit is contained in:
adel.kalimullin 2025-02-26 17:27:40 +03:00
parent 6a6d3af94e
commit f6d93ccf5b
16 changed files with 14 additions and 493 deletions

View file

@ -19,7 +19,7 @@ import ru.cg.webbpm.modules.database.api.dao.option.SortOrder;
import ru.cg.webbpm.modules.database.bean.filter.EntityFilter;
import ru.cg.webbpm.modules.database.bean.filter.EntityFilterGroup;
import ru.cg.webbpm.modules.database.bean.filter.FilterOperation;
import ru.cg.webbpm.modules.security.api.runtime.SecurityContext;
import ru.micord.ervu.account_applications.security.context.SecurityContext;
/**
* @author Adel Kalimullin
@ -90,8 +90,8 @@ public class RecruitmentAutoCompleteService extends AbstractAutocompleteService<
}
private List<String> getRecruitmentIdsForCurrentUser() {
String currentOrgUnitCode = securityContext.getCurrentOrgUnitCode();
return recruitmentDao.getRecruitmentIdsWithParentByOrgCode(currentOrgUnitCode);
String recruitmentId = securityContext.getRecruitmentId();
return recruitmentDao.getRecruitmentIdsWithParentByOrgCode(recruitmentId);
}
private EntityFilter getEntityFilterForRecruitmentIds(List<String> ids) {

View file

@ -9,6 +9,7 @@ import org.springframework.stereotype.Service;
import property.enums.DisplayType;
import property.grid.ColumnSort;
import ru.micord.ervu.account_applications.component.dao.RecruitmentDao;
import ru.micord.ervu.account_applications.security.context.SecurityContext;
import service.field.ComboBoxServiceImpl;
import ru.cg.webbpm.modules.database.api.bean.TableRow;
@ -16,7 +17,6 @@ import ru.cg.webbpm.modules.database.api.dao.option.LoadOptions;
import ru.cg.webbpm.modules.database.api.dao.option.SortOrder;
import ru.cg.webbpm.modules.database.bean.filter.EntityFilter;
import ru.cg.webbpm.modules.database.bean.filter.FilterOperation;
import ru.cg.webbpm.modules.security.api.runtime.SecurityContext;
/**
@ -26,13 +26,12 @@ import ru.cg.webbpm.modules.security.api.runtime.SecurityContext;
public class RecruitmentComboBoxService extends ComboBoxServiceImpl {
private final RecruitmentDao recruitmentDao;
private final SecurityContext securityContext;
public RecruitmentComboBoxService(RecruitmentDao recruitmentDao,
SecurityContext securityContext) {
public RecruitmentComboBoxService(RecruitmentDao recruitmentDao, SecurityContext securityContext) {
this.recruitmentDao = recruitmentDao;
this.securityContext = securityContext;
}
@Override
public List<ComboBoxModel> loadData() {
return load(new LoadOptions());
@ -102,7 +101,7 @@ public class RecruitmentComboBoxService extends ComboBoxServiceImpl {
}
private List<String> getRecruitmentIdsForCurrentUser() {
String currentOrgUnitCode = securityContext.getCurrentOrgUnitCode();
String currentOrgUnitCode = securityContext.getRecruitmentId();
return recruitmentDao.getRecruitmentIdsWithParentByOrgCode(currentOrgUnitCode);
}

View file

@ -18,7 +18,7 @@ import ru.cg.webbpm.modules.database.bean.annotation.LocalGraphSource;
import ru.cg.webbpm.modules.database.bean.entity_graph.EntityColumn;
import ru.cg.webbpm.modules.database.bean.filter.EntityFilter;
import ru.cg.webbpm.modules.database.bean.filter.FilterOperation;
import ru.cg.webbpm.modules.security.api.runtime.SecurityContext;
import ru.micord.ervu.account_applications.security.context.SecurityContext;
import ru.cg.webbpm.modules.standard_annotations.editor.ObjectRef;
import ru.cg.webbpm.modules.standard_annotations.validation.NotNull;
@ -70,7 +70,7 @@ public class RecruitmentGridService extends GridV2ServiceImpl {
}
private List<String> getRecruitmentIdsForCurrentUser() {
String currentOrgUnitCode = securityContext.getCurrentOrgUnitCode();
String currentOrgUnitCode = securityContext.getRecruitmentId();
return recruitmentDao.getRecruitmentIdsWithParentByOrgCode(currentOrgUnitCode);
}

View file

@ -67,7 +67,7 @@
Собранный образ фронтенда имеет возможность работать как полноценное standalone приложение, так и как удалённый модуль MFe. Для настройки Mfe следует указать следующие переменные:
* MFE_BASE_URL - указывается frontend/.env, либо в переменных среды сборки приложения. При изменении переменной приложение надо пересобирать. По умолчанию /mfe/business-metrics
* MFE_BASE_URL - указывается frontend/.env, либо в переменных среды сборки приложения. При изменении переменной приложение надо пересобирать. По умолчанию /mfe/account-applications
* backend.url - если необходимо настроить url бэкенда, его можно указать в frontend/src/resources/app.config.json

View file

@ -1,29 +0,0 @@
<div *ngIf="(currentSession | async)?.authorities.includes('USER_MANAGEMENT.USER.LIST') ||
(currentSession | async)?.authorities.includes('USER_MANAGEMENT.GROUP.LIST') ||
(currentSession | async)?.authorities.includes('USER_MANAGEMENT.ROLE.LIST') ||
(currentSession | async)?.authorities.includes('USER_MANAGEMENT.ORG_UNIT.LIST') ||
(currentSession | async)?.authorities.includes('USER_MANAGEMENT.AUTHORITY.LIST')" ngbDropdown class="nav-item" [placement]="placement">
<button class="nav-link bi bi-gear-fill" id="adminDropdownMenu" ngbDropdownToggle title="Администрирование"></button>
<div ngbDropdownMenu aria-labelledby="adminDropdownMenu">
<button *ngIf="(currentSession | async)?.authorities.includes('USER_MANAGEMENT.USER.LIST')"
routerLink="/user-management/users" ngbDropdownItem>
Пользователи
</button>
<button *ngIf="(currentSession | async)?.authorities.includes('USER_MANAGEMENT.GROUP.LIST')"
routerLink="/user-management/groups" ngbDropdownItem>
Группы
</button>
<button *ngIf="(currentSession | async)?.authorities.includes('USER_MANAGEMENT.ROLE.LIST')"
routerLink="/user-management/roles" ngbDropdownItem>
Роли
</button>
<button *ngIf="(currentSession | async)?.authorities.includes('USER_MANAGEMENT.ORG_UNIT.LIST')"
routerLink="/user-management/org-units" ngbDropdownItem>
Организации
</button>
<button *ngIf="(currentSession | async)?.authorities.includes('USER_MANAGEMENT.AUTHORITY.LIST')"
routerLink="/user-management/authorities" ngbDropdownItem>
Безопасность действий
</button>
</div>
</div>

View file

@ -1,11 +1,7 @@
<nav class="header" *ngIf="currentSession | async as session" id="webbpm-header">
<nav class="header" id="webbpm-header">
<div class="header-logo">
<div class="logo"><a routerLink="/"></a></div>
<div class="main-page">ЦЕНТРАЛИЗОВАННОЕ УПРАВЛЕНИЕ УЧЕТНЫМИ ЗАПИСЯМИ</div>
</div>
<div class="header-menu">
<admin-menu [placement]="'bottom'"></admin-menu>
<div ngbDropdown class="logout" log-out></div>
</div>
</nav>

View file

@ -1,27 +0,0 @@
<div class="confirm">
<div class="form-logo">
<div></div>
</div>
<div class="info">
<div>
<h2>Подтверждение почты</h2>
<div *ngIf="verificationStatus.toString() === 'VERIFYING'">
Подтверждение...
</div>
<div *ngIf="verificationStatus.toString() === 'VERIFIED'">
<div class="alert alert-success">
Адрес электронной почты успешно подтвержден
</div>
</div>
<div *ngIf="verificationStatus.toString() === 'FAILED'">
<div class="alert alert-danger">{{ errorMessage }}</div>
</div>
<div *ngIf="(currentSession | async) == null">
<a href="#/login"><span class="fa fa-lock"></span>Войти</a><br/>
<a href="#/registration">Зарегистрироваться</a>
</div>
</div>
</div>
</div>

View file

@ -1,9 +0,0 @@
<button class="nav-link bi bi-person-fill" ngbDropdownToggle title="Пользователь"></button>
<div ngbDropdownMenu *ngIf="currentSession | async as session">
<div class="user-info">
<div class="user-fio">{{session.fullUserName}}</div>
<div class="user-login">{{session.username}}</div>
<div class="user-department">{{getOrgUnitName()}}</div>
</div>
<button ngbDropdownItem *ngIf="isLogoutButtonVisible()" (click)="logout()">Выход</button>
</div>

View file

@ -1,49 +0,0 @@
<div class="form-signin">
<form #formComponent="ngForm">
<div class="alert alert-success" [hidden]="!confirmationSent">На ваш почтовый адрес было отправлено письмо. Подтвердите почту, чтобы войти в систему
</div>
<div class="alert alert-danger" [hidden]="!errorMessage">{{errorMessage}}</div>
<div class="logo">
<h2>ЦЕНТРАЛИЗОВАННОЕ УПРАВЛЕНИЕ<br />УЧЕТНЫМИ ЗАПИСЯМИ</h2>
</div>
<div class="row">
<div class="input-group">
<input type="text" name="username" class="form-control" placeholder=" " required autofocus [(ngModel)]="username" maxlength="100">
<label>Логин</label>
</div>
</div>
<div class="row">
<div class="input-group">
<input
[type]="passwordType ? 'text' : 'password'"
name="password"
class="form-control field-password-view"
placeholder=" " required
[(ngModel)]="password"
maxlength="100"
>
<label>Пароль</label>
<div class="input-group-append">
<span class="input-group-text">
<i
(click)="togglePasswordType()"
class="fa"
[ngClass]="{
'fa-eye': passwordType,
'fa-eye-slash': !passwordType
}"
></i>
</span>
</div>
</div>
<!--<div class="msg-text"><a href="#/reset-password">Восстановить пароль</a></div>-->
</div>
<div class="btn-box">
<!--<esia-login-button></esia-login-button>-->
<button type="submit" class="btn btn-primary" (click)="formComponent.form.valid && login()">Войти</button>
</div>
</form>
</div>

View file

@ -1,103 +0,0 @@
<div class="form-signup">
<div class="form-logo">
<div></div>
</div>
<div class="form-new-password">
<form #formComponent="ngForm">
<div [hidden]="!errorMessage" class="alert alert-danger">{{ errorMessage }}</div>
<p class="has-account">Вспомнили пароль?
<a href="#/login"><span class="fa fa-lock"></span>Войти</a></p>
<p class="has-account">Задайте новый пароль</p>
<div class="row">
<label>Пароль</label>
<div class="input-group">
<input
#passwordInput="ngModel"
[(ngModel)]="password"
[type]="passwordType ? 'text' : 'password'"
class="form-control"
maxlength="32"
minlength="6"
name="password"
pattern="^(?=.*[a-zA-Z])(?=.*[0-9])[a-zA-Z0-9]+$"
required
(change)="validPasswords()"
>
<div class="input-group-append">
<span class="input-group-text">
<i
(click)="togglePasswordType()"
class="fa"
[ngClass]="{
'fa-eye': passwordType,
'fa-eye-slash': !passwordType
}"
></i>
</span>
</div>
</div>
<div *ngIf="passwordInput.invalid && (passwordInput.dirty || passwordInput.touched)">
<div *ngIf="passwordInput.errors.required" class="msg-alert">Поле обязательно
</div>
<div *ngIf="passwordInput.errors.minlength" class="msg-alert">Пароль должен
содержать как минимум 6 символов
</div>
<div *ngIf="passwordInput.errors.pattern" class="msg-alert">Пароль должен
содержать заглавные и прописные буквы и как минимум 1 цифру
</div>
</div>
</div>
<div class="row">
<label>Подтверждение пароля</label>
<div class="input-group">
<input
#confirmPasswordInput="ngModel"
[(ngModel)]="confirmPassword"
[type]="confirmPasswordType ? 'text' : 'password'"
class="form-control"
maxlength="32"
minlength="6"
name="confirmPassword"
pattern="^(?=.*[a-zA-Z])(?=.*[0-9])[a-zA-Z0-9]+$"
required
(change)="validPasswords()"
>
<div class="input-group-append">
<span class="input-group-text">
<i
(click)="toggleConfirmPasswordType()"
class="fa"
[ngClass]="{
'fa-eye': confirmPasswordType,
'fa-eye-slash': !confirmPasswordType
}"
></i>
</span>
</div>
</div>
<div *ngIf="confirmPasswordInput.invalid && (confirmPasswordInput.dirty || confirmPasswordInput.touched)">
<div *ngIf="confirmPasswordInput.errors.required" class="msg-alert">Поле обязательно
</div>
<div *ngIf="confirmPasswordInput.errors.minlength" class="msg-alert">Пароль должен
содержать как минимум 6 символов
</div>
<div *ngIf="confirmPasswordInput.errors.pattern" class="msg-alert">Пароль должен
содержать заглавные и прописные буквы и как минимум 1 цифру
</div>
</div>
</div>
<div class="reset-password-btn-box">
<button
(click)="formComponent.form.valid && validPasswords() && changePassword()"
[disabled]="!formComponent.form.valid && !validPasswords()"
class="btn btn-primary"
type="submit"
>
Изменить пароль
</button>
</div>
</form>
</div>
</div>

View file

@ -1,121 +0,0 @@
<div class="form-signup">
<div class="form-logo">
<div></div>
</div>
<div class="form-register">
<form #formComponent="ngForm">
<div [hidden]="!errorMessage" class="alert alert-danger">{{ errorMessage }}</div>
<h2>Регистрация</h2>
<p class="has-account">Уже зарегистрированы?
<a href="#/login"><span class="fa fa-lock"></span>Войти</a></p>
<div class="row">
<label>Имя</label>
<input
#name="ngModel"
[(ngModel)]="username"
class="form-control"
maxlength="100"
name="username"
required
type="text"
>
<div *ngIf="name.invalid && (name.dirty || name.touched)">
<div *ngIf="name.errors.required" class="msg-alert">Поле обязательно</div>
</div>
</div>
<div class="row">
<label>Адрес эл. почты</label>
<input
#emailInput="ngModel"
[(ngModel)]="email"
class="form-control"
email
maxlength="100"
name="email"
required
type="email"
>
<div *ngIf="emailInput.invalid && (emailInput.dirty || emailInput.touched)">
<div *ngIf="emailInput.errors.required" class="msg-alert">Поле обязательно</div>
<div *ngIf="emailInput.errors.email" class="msg-alert">Неверный формат адреса
эл. почты
</div>
</div>
</div>
<div class="row">
<label>Номер телефона</label>
<international-phone-number
#phoneInput="ngModel"
[(ngModel)]="phoneNumber"
[defaultCountry]="'ru'"
[pattern]="'^\\+(?!7 ?\\d{11})[0-9 ]+$'"
maxlength="20"
minlength="8"
name="phoneNumber"
placeholder="+79991112233"
(focusout)="phoneInputFocusOut()"
required
></international-phone-number>
<div *ngIf="phoneInput.invalid && (phoneInput.dirty || phoneIsTouched)">
<div *ngIf="phone.selectedCountry">
<div *ngIf="phoneHasOnlyDialCode()" class="msg-alert">Поле обязательно</div>
<div *ngIf="!phoneHasOnlyDialCode()" class="msg-alert">Введите корректный номер</div>
</div>
<div *ngIf="!phone.selectedCountry">
<div *ngIf="phoneInput.errors.required" class="msg-alert">Поле обязательно</div>
<div *ngIf="!phoneInput.errors.required" class="msg-alert">Введите код страны</div>
</div>
</div>
</div>
<div class="row">
<label>Пароль</label>
<div class="input-group">
<input
#passwordInput="ngModel"
[(ngModel)]="password"
[type]="fieldType ? 'text' : 'password'"
class="form-control"
maxlength="32"
minlength="8"
name="password"
[pattern]="passwordPattern"
required
>
<div class="input-group-append">
<span class="input-group-text">
<i
(click)="toggleFieldType()"
class="fa"
[ngClass]="{
'fa-eye': fieldType,
'fa-eye-slash': !fieldType
}"
></i>
</span>
</div>
</div>
<div *ngIf="passwordInput.invalid && (passwordInput.dirty || passwordInput.touched)">
<div *ngIf="passwordInput.errors.required" class="msg-alert">Поле обязательно
</div>
<div *ngIf="passwordInput.errors.minlength" class="msg-alert">Пароль должен
содержать как минимум 8 символов
</div>
<div *ngIf="passwordInput.errors.pattern" class="msg-alert" [innerText]="passwordPatternErrorMessage">
</div>
</div>
</div>
<div class="register-btn-box">
<button
(click)="formComponent.form.valid && register()"
[disabled]="!formComponent.form.valid"
class="btn btn-primary"
type="submit"
>
Зарегистрироваться
</button>
</div>
<div *ngIf="consent" [innerHTML]="consent" class="consent"></div>
</form>
</div>
</div>

View file

@ -1,45 +0,0 @@
<div class="form-signup">
<div class="form-logo">
<div></div>
</div>
<div class="form-reset-password">
<form #formComponent="ngForm">
<div [hidden]="!errorMessage" class="alert alert-danger">{{ errorMessage }}</div>
<p class="has-account">Вспомнили пароль?
<a href="#/login"><span class="fa fa-lock"></span>Войти</a></p>
<p class="has-account">Укажите адрес эл. почты, который был указан при регистрации,
на него пришлем временный пароль. Пароль сможете поменять в личном кабинете.
</p>
<div class="row">
<input
#emailInput="ngModel"
[(ngModel)]="email"
class="form-control"
email
maxlength="100"
name="email"
required
type="email"
>
<label>Адрес эл. почты</label>
<div *ngIf="emailInput.invalid && (emailInput.dirty || emailInput.touched)" class="msg-text">
<div *ngIf="emailInput.errors.required" class="msg-alert">Поле обязательно</div>
<div *ngIf="emailInput.errors.email" class="msg-alert">Неверный формат адреса эл. почты
</div>
</div>
</div>
<div class="btn-box">
<button
(click)="formComponent.form.valid && resetPassword()"
[disabled]="!formComponent.form.valid"
class="btn btn-primary"
type="submit"
>
Восстановить
</button>
</div>
</form>
</div>
</div>

View file

@ -28,7 +28,7 @@
<label>Domain id</label>
<div class="input-group">
<input type="text" name="domain_id" class="form-control" placeholder="Id подразделения" required
[(ngModel)]="recruitmentId">
[(ngModel)]="domain_id">
</div>
</div>

View file

@ -11,7 +11,7 @@ export class TokenFormComponent {
name: string = '';
realm: string = '';
recruitmentId: string = '';
domain_id: string = '';
role: string = '';
private readonly encodedHeader = this.encodeBase64Url(JSON.stringify({
@ -32,7 +32,7 @@ export class TokenFormComponent {
let claims = {
name: this.name,
realm: this.realm,
recruitmentId: this.recruitmentId,
domain_id: this.domain_id,
roles: [this.role]
};
return `${this.encodedHeader}.${this.encodeBase64Url(JSON.stringify(claims))}.`

View file

@ -1,88 +0,0 @@
import {RouterModule, Routes} from "@angular/router";
import {NgModule} from "@angular/core";
import {
AuthenticationGuard,
ConfirmExitGuard
} from "@webbpm/base-package";
const routes: Routes = [
{
path: 'user-management',
canActivate: [AuthenticationGuard],
children: [
{
path: 'users',
loadChildren: 'generated-sources/page-user-management-users.module#PageusermanagementusersModule',
canActivate: [ConfirmExitGuard]
},
{
path: 'users/new',
loadChildren: 'generated-sources/page-user-management-user-create.module#PageusermanagementusercreateModule',
canActivate: [ConfirmExitGuard]
},
{
path: 'users/:id',
loadChildren: 'generated-sources/page-user-management-user-edit.module#PageusermanagementusereditModule',
canActivate: [ConfirmExitGuard]
},
{
path: 'org-units',
loadChildren: 'generated-sources/page-user-management-org-units.module#PageusermanagementorgunitsModule',
canActivate: [ConfirmExitGuard]
},
{
path: 'org-units/new',
loadChildren: 'generated-sources/page-user-management-org-unit.module#PageusermanagementorgunitModule',
canActivate: [ConfirmExitGuard]
},
{
path: 'org-units/:id',
loadChildren: 'generated-sources/page-user-management-org-unit.module#PageusermanagementorgunitModule',
canActivate: [ConfirmExitGuard]
},
{
path: 'roles',
loadChildren: 'generated-sources/page-user-management-roles.module#PageusermanagementrolesModule',
canActivate: [ConfirmExitGuard]
},
{
path: 'roles/new',
loadChildren: 'generated-sources/page-user-management-role.module#PageusermanagementroleModule',
canActivate: [ConfirmExitGuard]
},
{
path: 'roles/:id',
loadChildren: 'generated-sources/page-user-management-role.module#PageusermanagementroleModule',
canActivate: [ConfirmExitGuard]
},
{
path: 'groups',
loadChildren: 'generated-sources/page-user-management-groups.module#PageusermanagementgroupsModule',
canActivate: [ConfirmExitGuard]
},
{
path: 'groups/new',
loadChildren: 'generated-sources/page-user-management-group-create.module#PageusermanagementgroupcreateModule',
canActivate: [ConfirmExitGuard]
},
{
path: 'groups/:id',
loadChildren: 'generated-sources/page-user-management-group-edit.module#PageusermanagementgroupeditModule',
canActivate: [ConfirmExitGuard]
},
{
path: 'authorities',
loadChildren: 'generated-sources/page-user-management-authorities.module#PageusermanagementauthoritiesModule',
canActivate: [ConfirmExitGuard]
}
]
}
];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
})
export class UserManagementRoutingModule {
}

View file

@ -16,7 +16,6 @@ import {
SecurityModule,
} from "@webbpm/base-package";
import {AppRoutingModule} from "../app/app-routing.module";
import {UserManagementRoutingModule} from "./user-management-routing.module";
import {GlobalErrorHandler} from "./handler/global-error.handler.prod";
import {DEFAULT_HTTP_INTERCEPTOR_PROVIDERS} from "./interceptor/default-interceptors.prod";
import {TokenFormComponent} from "./component/token-form.component";
@ -33,11 +32,9 @@ let IMPORTS = [
ToastNoAnimationModule.forRoot(),
AgGridModule,
AppRoutingModule,
UserManagementRoutingModule,
BpmnModule,
CoreModule,
ComponentsModule,
SecurityModule,
AppModule,
WebbpmRoutingModule
];