fix tenant select
This commit is contained in:
parent
a9468abe61
commit
30e5ed504a
|
@ -1,18 +1,16 @@
|
|||
package org.opencdmp.service.tenant;
|
||||
|
||||
import org.opencdmp.model.Tenant;
|
||||
import org.opencdmp.model.persist.TenantPersist;
|
||||
import gr.cite.tools.exception.MyApplicationException;
|
||||
import gr.cite.tools.exception.MyForbiddenException;
|
||||
import gr.cite.tools.exception.MyNotFoundException;
|
||||
import gr.cite.tools.exception.MyValidationException;
|
||||
import gr.cite.tools.fieldset.FieldSet;
|
||||
import org.opencdmp.model.Tenant;
|
||||
import org.opencdmp.model.persist.TenantPersist;
|
||||
|
||||
import javax.crypto.BadPaddingException;
|
||||
import javax.crypto.IllegalBlockSizeException;
|
||||
import javax.crypto.NoSuchPaddingException;
|
||||
import javax.crypto.SecretKey;
|
||||
import javax.crypto.spec.IvParameterSpec;
|
||||
import javax.management.InvalidApplicationException;
|
||||
import java.security.InvalidAlgorithmParameterException;
|
||||
import java.security.InvalidKeyException;
|
||||
|
@ -26,4 +24,6 @@ public interface TenantService {
|
|||
InvalidAlgorithmParameterException, NoSuchPaddingException, IllegalBlockSizeException, NoSuchAlgorithmException, BadPaddingException, InvalidKeyException;
|
||||
|
||||
void deleteAndSave(UUID id) throws MyForbiddenException, InvalidApplicationException;
|
||||
|
||||
List<Tenant> myTenants(FieldSet fieldSet) throws MyForbiddenException;
|
||||
}
|
||||
|
|
|
@ -1,8 +1,12 @@
|
|||
package org.opencdmp.service.tenant;
|
||||
|
||||
import gr.cite.commons.web.authz.service.AuthorizationService;
|
||||
import gr.cite.commons.web.oidc.principal.CurrentPrincipalResolver;
|
||||
import gr.cite.commons.web.oidc.principal.MyPrincipal;
|
||||
import gr.cite.commons.web.oidc.principal.extractor.ClaimExtractor;
|
||||
import gr.cite.tools.data.builder.BuilderFactory;
|
||||
import gr.cite.tools.data.deleter.DeleterFactory;
|
||||
import gr.cite.tools.data.query.Ordering;
|
||||
import gr.cite.tools.data.query.QueryFactory;
|
||||
import gr.cite.tools.exception.MyApplicationException;
|
||||
import gr.cite.tools.exception.MyForbiddenException;
|
||||
|
@ -14,6 +18,7 @@ import gr.cite.tools.logging.LoggerService;
|
|||
import gr.cite.tools.logging.MapLogEntry;
|
||||
import org.opencdmp.authorization.AuthorizationFlags;
|
||||
import org.opencdmp.authorization.AuthorizationProperties;
|
||||
import org.opencdmp.authorization.ClaimNames;
|
||||
import org.opencdmp.authorization.Permission;
|
||||
import org.opencdmp.commons.enums.IsActive;
|
||||
import org.opencdmp.commons.scope.tenant.TenantScope;
|
||||
|
@ -31,6 +36,7 @@ import org.opencdmp.model.Tenant;
|
|||
import org.opencdmp.model.builder.TenantBuilder;
|
||||
import org.opencdmp.model.deleter.TenantDeleter;
|
||||
import org.opencdmp.model.persist.TenantPersist;
|
||||
import org.opencdmp.query.TenantQuery;
|
||||
import org.opencdmp.query.UserCredentialQuery;
|
||||
import org.opencdmp.query.UserRoleQuery;
|
||||
import org.opencdmp.service.keycloak.KeycloakService;
|
||||
|
@ -48,6 +54,7 @@ import java.security.InvalidAlgorithmParameterException;
|
|||
import java.security.InvalidKeyException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.time.Instant;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
|
@ -73,6 +80,8 @@ public class TenantServiceImpl implements TenantService {
|
|||
private final AuthorizationProperties authorizationProperties;
|
||||
private final TenantScope tenantScope;
|
||||
private final QueryFactory queryFactory;
|
||||
private final CurrentPrincipalResolver currentPrincipalResolver;
|
||||
private final ClaimExtractor claimExtractor;
|
||||
|
||||
|
||||
@Autowired
|
||||
|
@ -83,7 +92,7 @@ public class TenantServiceImpl implements TenantService {
|
|||
BuilderFactory builderFactory,
|
||||
ConventionService conventionService,
|
||||
MessageSource messageSource,
|
||||
ErrorThesaurusProperties errors, TenantTouchedIntegrationEventHandler tenantTouchedIntegrationEventHandler, TenantRemovalIntegrationEventHandler tenantRemovalIntegrationEventHandler, KeycloakService keycloakService, AuthorizationProperties authorizationProperties, TenantScope tenantScope, QueryFactory queryFactory) {
|
||||
ErrorThesaurusProperties errors, TenantTouchedIntegrationEventHandler tenantTouchedIntegrationEventHandler, TenantRemovalIntegrationEventHandler tenantRemovalIntegrationEventHandler, KeycloakService keycloakService, AuthorizationProperties authorizationProperties, TenantScope tenantScope, QueryFactory queryFactory, CurrentPrincipalResolver currentPrincipalResolver, ClaimExtractor claimExtractor) {
|
||||
this.entityManager = entityManager;
|
||||
this.authorizationService = authorizationService;
|
||||
this.deleterFactory = deleterFactory;
|
||||
|
@ -97,6 +106,8 @@ public class TenantServiceImpl implements TenantService {
|
|||
this.authorizationProperties = authorizationProperties;
|
||||
this.tenantScope = tenantScope;
|
||||
this.queryFactory = queryFactory;
|
||||
this.currentPrincipalResolver = currentPrincipalResolver;
|
||||
this.claimExtractor = claimExtractor;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -177,8 +188,6 @@ public class TenantServiceImpl implements TenantService {
|
|||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void deleteAndSave(UUID id) throws MyForbiddenException, InvalidApplicationException {
|
||||
logger.debug("deleting : {}", id);
|
||||
|
@ -192,5 +201,38 @@ public class TenantServiceImpl implements TenantService {
|
|||
this.tenantRemovalIntegrationEventHandler.handle(tenantRemovalIntegrationEvent);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public List<Tenant> myTenants(FieldSet fieldSet) throws MyForbiddenException {
|
||||
logger.debug("my tenants");
|
||||
|
||||
MyPrincipal principal = this.currentPrincipalResolver.currentPrincipal();
|
||||
List<String> tenants = this.claimExtractor.asStrings(principal, ClaimNames.TenantCodesClaimName);
|
||||
List<Tenant> models = new ArrayList<>();
|
||||
|
||||
if (tenants != null && !tenants.isEmpty()) {
|
||||
if (fieldSet == null || fieldSet.isEmpty()) {
|
||||
fieldSet = new BaseFieldSet(
|
||||
Tenant._id,
|
||||
Tenant._code,
|
||||
Tenant._name);
|
||||
}
|
||||
|
||||
TenantQuery query = this.queryFactory.query(TenantQuery.class).codes(tenants).isActive(IsActive.Active);
|
||||
query.setOrder(new Ordering().addAscending(Tenant._name));
|
||||
List<TenantEntity> data = query.collectAs(fieldSet);
|
||||
models.addAll(this.builderFactory.builder(TenantBuilder.class).build(fieldSet, data));
|
||||
|
||||
if (tenants.contains(this.tenantScope.getDefaultTenantCode())){
|
||||
Tenant tenant = new Tenant();
|
||||
tenant.setCode(this.tenantScope.getDefaultTenantCode());
|
||||
tenant.setName(this.messageSource.getMessage("DefaultTenant_Name", new Object[]{}, LocaleContextHolder.getLocale()));
|
||||
models.addFirst(tenant);
|
||||
}
|
||||
}
|
||||
return models;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -1,17 +1,16 @@
|
|||
package org.opencdmp.controllers;
|
||||
|
||||
import org.opencdmp.audit.AuditableAction;
|
||||
import org.opencdmp.authorization.ClaimNames;
|
||||
import org.opencdmp.commons.scope.tenant.TenantScope;
|
||||
import org.opencdmp.models.Account;
|
||||
import org.opencdmp.models.AccountBuilder;
|
||||
import gr.cite.commons.web.oidc.principal.CurrentPrincipalResolver;
|
||||
import gr.cite.commons.web.oidc.principal.MyPrincipal;
|
||||
import gr.cite.commons.web.oidc.principal.extractor.ClaimExtractor;
|
||||
import gr.cite.tools.auditing.AuditService;
|
||||
import gr.cite.tools.fieldset.BaseFieldSet;
|
||||
import gr.cite.tools.fieldset.FieldSet;
|
||||
import gr.cite.tools.logging.LoggerService;
|
||||
import org.opencdmp.audit.AuditableAction;
|
||||
import org.opencdmp.model.Tenant;
|
||||
import org.opencdmp.models.Account;
|
||||
import org.opencdmp.models.AccountBuilder;
|
||||
import org.opencdmp.service.tenant.TenantService;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
|
@ -21,27 +20,26 @@ import org.springframework.web.bind.annotation.RestController;
|
|||
|
||||
import javax.management.InvalidApplicationException;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@RestController
|
||||
@RequestMapping(value = { "/api/principal/" })
|
||||
@RequestMapping("/api/principal/")
|
||||
public class PrincipalController {
|
||||
private static final LoggerService logger = new LoggerService(LoggerFactory.getLogger(PrincipalController.class));
|
||||
private final AuditService auditService;
|
||||
|
||||
private final CurrentPrincipalResolver currentPrincipalResolver;
|
||||
private final AccountBuilder accountBuilder;
|
||||
private final ClaimExtractor claimExtractor;
|
||||
private final TenantService tenantService;
|
||||
|
||||
@Autowired
|
||||
public PrincipalController(
|
||||
CurrentPrincipalResolver currentPrincipalResolver,
|
||||
AccountBuilder accountBuilder,
|
||||
AuditService auditService, ClaimExtractor claimExtractor) {
|
||||
AuditService auditService, TenantService tenantService) {
|
||||
this.currentPrincipalResolver = currentPrincipalResolver;
|
||||
this.accountBuilder = accountBuilder;
|
||||
this.auditService = auditService;
|
||||
this.claimExtractor = claimExtractor;
|
||||
this.tenantService = tenantService;
|
||||
}
|
||||
|
||||
@RequestMapping(path = "me", method = RequestMethod.GET )
|
||||
|
@ -80,16 +78,15 @@ public class PrincipalController {
|
|||
}
|
||||
|
||||
@GetMapping("my-tenants")
|
||||
public List<String> myTenants() {
|
||||
public List<Tenant> myTenants(FieldSet fieldSet) {
|
||||
logger.debug("my-tenants");
|
||||
|
||||
MyPrincipal principal = this.currentPrincipalResolver.currentPrincipal();
|
||||
List<String> tenants = this.claimExtractor.asStrings(principal, ClaimNames.TenantCodesClaimName);
|
||||
List<Tenant> models = this.tenantService.myTenants(fieldSet);
|
||||
|
||||
this.auditService.track(AuditableAction.Principal_MyTenants);
|
||||
//auditService.trackIdentity(AuditableAction.IdentityTracking_Action);
|
||||
|
||||
return tenants == null ? null : tenants.stream().distinct().collect(Collectors.toList());
|
||||
return models;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,10 +1,5 @@
|
|||
package org.opencdmp.models;
|
||||
|
||||
import org.opencdmp.commons.JsonHandlingService;
|
||||
import org.opencdmp.commons.scope.user.UserScope;
|
||||
import org.opencdmp.commons.types.user.AdditionalInfoEntity;
|
||||
import org.opencdmp.data.TenantEntityManager;
|
||||
import org.opencdmp.data.UserEntity;
|
||||
import gr.cite.commons.web.authz.configuration.AuthorizationConfiguration;
|
||||
import gr.cite.commons.web.authz.configuration.Permission;
|
||||
import gr.cite.commons.web.oidc.principal.CurrentPrincipalResolver;
|
||||
|
@ -13,6 +8,11 @@ import gr.cite.commons.web.oidc.principal.extractor.ClaimExtractor;
|
|||
import gr.cite.commons.web.oidc.principal.extractor.ClaimExtractorKeys;
|
||||
import gr.cite.tools.fieldset.BaseFieldSet;
|
||||
import gr.cite.tools.fieldset.FieldSet;
|
||||
import org.opencdmp.commons.JsonHandlingService;
|
||||
import org.opencdmp.commons.scope.user.UserScope;
|
||||
import org.opencdmp.commons.types.user.AdditionalInfoEntity;
|
||||
import org.opencdmp.data.TenantEntityManager;
|
||||
import org.opencdmp.data.UserEntity;
|
||||
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
|
||||
import org.springframework.context.annotation.Scope;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
@ -21,7 +21,7 @@ import javax.management.InvalidApplicationException;
|
|||
import java.util.*;
|
||||
|
||||
@Component
|
||||
@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
|
||||
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
|
||||
public class AccountBuilder {
|
||||
|
||||
private final ClaimExtractor claimExtractor;
|
||||
|
@ -91,13 +91,13 @@ public class AccountBuilder {
|
|||
}
|
||||
}
|
||||
if (fields.hasField(Account._roles)) {
|
||||
List<String> roles = claimExtractor.roles(currentPrincipalResolver.currentPrincipal());
|
||||
List<String> roles = this.claimExtractor.roles(this.currentPrincipalResolver.currentPrincipal());
|
||||
model.setRoles(roles);
|
||||
}
|
||||
if (fields.hasField(Account._permissions)) {
|
||||
List<String> roles = claimExtractor.roles(currentPrincipalResolver.currentPrincipal());
|
||||
Set<String> permissions = authorizationConfiguration.permissionsOfRoles(roles);
|
||||
for (Map.Entry<String, Permission> permissionEntry : authorizationConfiguration.getRawPolicies().entrySet()){
|
||||
List<String> roles = this.claimExtractor.roles(this.currentPrincipalResolver.currentPrincipal());
|
||||
Set<String> permissions = this.authorizationConfiguration.permissionsOfRoles(roles);
|
||||
for (Map.Entry<String, Permission> permissionEntry : this.authorizationConfiguration.getRawPolicies().entrySet()){
|
||||
if (permissionEntry.getValue().getAllowAuthenticated()){
|
||||
permissions.add(permissionEntry.getKey());
|
||||
}
|
||||
|
|
|
@ -28,3 +28,5 @@ Validation.MissingFields= missing fields: {0}
|
|||
Validation.InvalidDescriptionTemplateMultiplicity= {0} can not be used
|
||||
Validation.InvalidDescriptionTemplateMultiplicityOnDMP= Description Templates has multiplicity errors
|
||||
Validation_UrlRequired={0} is not valid url
|
||||
|
||||
DefaultTenant_Name=Default
|
|
@ -4,6 +4,7 @@ import { Observable } from 'rxjs';
|
|||
import { ConfigurationService } from '../configuration/configuration.service';
|
||||
import { BaseHttpV2Service } from '../http/base-http-v2.service';
|
||||
import { map } from 'rxjs/operators';
|
||||
import { Tenant } from '@app/core/model/tenant/tenant';
|
||||
|
||||
@Injectable()
|
||||
export class PrincipalService {
|
||||
|
@ -20,8 +21,8 @@ export class PrincipalService {
|
|||
return this.http.get<AppAccount>(url, options);
|
||||
}
|
||||
|
||||
public myTenants(options?: Object): Observable<Array<string>> {
|
||||
public myTenants(options?: Object): Observable<Array<Tenant>> {
|
||||
const url = `${this.apiBase}/my-tenants`;
|
||||
return this.http.get<Array<string>>(url, options);
|
||||
return this.http.get<Array<Tenant>>(url, options);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -64,9 +64,9 @@ export class PostLoginComponent extends BaseComponent implements OnInit {
|
|||
this.principalService.myTenants({ params: params }).subscribe(myTenants => {
|
||||
if (myTenants) {
|
||||
if (myTenants.length > 1) {
|
||||
this.tenants = myTenants.map(function (code) { return { 'code': code }; });
|
||||
this.tenants = myTenants;
|
||||
} else if (myTenants.length === 1) {
|
||||
this.authService.selectedTenant(myTenants[0]);
|
||||
this.authService.selectedTenant(myTenants[0]?.code);
|
||||
this.loadUser();
|
||||
} else {
|
||||
this.authService.selectedTenant(null);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<mat-button-toggle-group class="tenant-menu" vertical (change)="onTenantSelected($event)" [value]="this.currentTenant">
|
||||
<div *ngFor="let tenant of tenants | async">
|
||||
<mat-button-toggle class="tenant-button" [value]="tenant">{{ tenant }}</mat-button-toggle>
|
||||
<mat-button-toggle class="tenant-button" [value]="tenant.code">{{ tenant.name }}</mat-button-toggle>
|
||||
</div>
|
||||
</mat-button-toggle-group>
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import { Component, EventEmitter, OnInit, Output } from "@angular/core";
|
||||
import { MatButtonToggleChange } from "@angular/material/button-toggle";
|
||||
import { Router } from "@angular/router";
|
||||
import { Tenant } from "@app/core/model/tenant/tenant";
|
||||
import { AuthService } from "@app/core/services/auth/auth.service";
|
||||
import { PrincipalService } from "@app/core/services/http/principal.service";
|
||||
import { BaseComponent } from "@common/base/base.component";
|
||||
|
@ -16,7 +17,7 @@ import { takeUntil } from "rxjs/operators";
|
|||
styleUrls: ['tenant-switch.component.scss']
|
||||
})
|
||||
export class TenantSwitchComponent extends BaseComponent implements OnInit {
|
||||
tenants: Observable<Array<string>>;
|
||||
tenants: Observable<Array<Tenant>>;
|
||||
|
||||
constructor(
|
||||
private router: Router,
|
||||
|
@ -36,7 +37,7 @@ export class TenantSwitchComponent extends BaseComponent implements OnInit {
|
|||
//this.tenantChange.emit(this.getCurrentLanguage())
|
||||
}
|
||||
|
||||
loadUserTenants(): Observable<Array<string>> {
|
||||
loadUserTenants(): Observable<Array<Tenant>> {
|
||||
const params = new BaseHttpParams();
|
||||
params.interceptorContext = {
|
||||
excludedInterceptors: [InterceptorType.TenantHeaderInterceptor]
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
<mat-label>Tenant</mat-label>
|
||||
<mat-select placeholder="Tenant" [formControl]="this.tenantFormGroup.get('tenantCode')">
|
||||
<ng-container *ngFor="let tenant of tenants | async">
|
||||
<mat-option [value]="tenant">{{ tenant }}</mat-option>
|
||||
<mat-option [value]="tenant.code">{{ tenant.name }}</mat-option>
|
||||
</ng-container>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
|
|
|
@ -38,6 +38,7 @@ import { ReferenceTypeService } from '@app/core/services/reference-type/referenc
|
|||
import { SingleAutoCompleteConfiguration } from '@app/library/auto-complete/single/single-auto-complete-configuration';
|
||||
import { ReferenceSourceType } from '@app/core/common/enum/reference-source-type';
|
||||
import { ReferenceType } from '@app/core/model/reference-type/reference-type';
|
||||
import { Tenant } from '@app/core/model/tenant/tenant';
|
||||
|
||||
@Component({
|
||||
selector: 'app-user-profile',
|
||||
|
@ -61,7 +62,7 @@ export class UserProfileComponent extends BaseComponent implements OnInit, OnDes
|
|||
errorMessages = [];
|
||||
nestedCount = [];
|
||||
nestedIndex = 0;
|
||||
tenants: Observable<Array<string>>;
|
||||
tenants: Observable<Array<Tenant>>;
|
||||
expandedPreferences: boolean = false;
|
||||
|
||||
organisationsSingleAutoCompleteConfiguration: SingleAutoCompleteConfiguration;
|
||||
|
@ -438,7 +439,7 @@ export class UserProfileComponent extends BaseComponent implements OnInit, OnDes
|
|||
}
|
||||
|
||||
// Switch Tenant
|
||||
loadUserTenants(): Observable<Array<string>> {
|
||||
loadUserTenants(): Observable<Array<Tenant>> {
|
||||
const params = new BaseHttpParams();
|
||||
params.interceptorContext = {
|
||||
excludedInterceptors: [InterceptorType.TenantHeaderInterceptor]
|
||||
|
|
Loading…
Reference in New Issue