Browse Source

Refactoring

pull/3443/head
Thomas Kaul 1 year ago
parent
commit
e272d69aa4
  1. 66
      apps/api/src/app/portfolio/portfolio.controller.ts
  2. 19
      apps/api/src/interceptors/redact-values-in-response/redact-values-in-response.interceptor.ts
  3. 9
      apps/api/src/interceptors/redact-values-in-response/redact-values-in-response.module.ts
  4. 9
      apps/api/src/services/user-helper/user-helper.module.ts
  5. 30
      apps/api/src/services/user-helper/user-helper.service.ts
  6. 24
      libs/common/src/lib/permissions.ts

66
apps/api/src/app/portfolio/portfolio.controller.ts

@ -14,7 +14,6 @@ import { ApiService } from '@ghostfolio/api/services/api/api.service';
import { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.service';
import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service';
import { ImpersonationService } from '@ghostfolio/api/services/impersonation/impersonation.service';
import { UserHelperService } from '@ghostfolio/api/services/user-helper/user-helper.service';
import {
DEFAULT_CURRENCY,
HEADER_KEY_IMPERSONATION
@ -28,6 +27,10 @@ import {
PortfolioPublicDetails,
PortfolioReport
} from '@ghostfolio/common/interfaces';
import {
hasReadRestrictedAccessPermission,
isRestrictedView
} from '@ghostfolio/common/permissions';
import type {
DateRange,
GroupBy,
@ -66,7 +69,6 @@ export class PortfolioController {
private readonly orderService: OrderService,
private readonly portfolioService: PortfolioService,
@Inject(REQUEST) private readonly request: RequestWithUser,
private readonly userHelperService: UserHelperService,
private readonly userService: UserService
) {}
@ -86,11 +88,6 @@ export class PortfolioController {
let hasDetails = true;
let hasError = false;
const hasReadRestrictedAccessPermission =
this.userHelperService.hasReadRestrictedAccessPermission({
impersonationId,
user: this.request.user
});
if (this.configurationService.get('ENABLE_FEATURE_SUBSCRIPTION')) {
hasDetails = this.request.user.subscription.type === 'Premium';
@ -119,8 +116,11 @@ export class PortfolioController {
let portfolioSummary = summary;
if (
hasReadRestrictedAccessPermission ||
this.userHelperService.isRestrictedView(this.request.user)
hasReadRestrictedAccessPermission({
impersonationId,
user: this.request.user
}) ||
isRestrictedView(this.request.user)
) {
const totalInvestment = Object.values(holdings)
.map(({ investment }) => {
@ -160,8 +160,11 @@ export class PortfolioController {
if (
hasDetails === false ||
hasReadRestrictedAccessPermission ||
this.userHelperService.isRestrictedView(this.request.user)
hasReadRestrictedAccessPermission({
impersonationId,
user: this.request.user
}) ||
isRestrictedView(this.request.user)
) {
portfolioSummary = nullifyValuesInObject(summary, [
'cash',
@ -228,12 +231,6 @@ export class PortfolioController {
@Query('range') dateRange: DateRange = 'max',
@Query('tags') filterByTags?: string
): Promise<PortfolioDividends> {
const hasReadRestrictedAccessPermission =
this.userHelperService.hasReadRestrictedAccessPermission({
impersonationId,
user: this.request.user
});
const filters = this.apiService.buildFiltersFromQueryParams({
filterByAccounts,
filterByAssetClasses,
@ -261,8 +258,11 @@ export class PortfolioController {
});
if (
hasReadRestrictedAccessPermission ||
this.userHelperService.isRestrictedView(this.request.user)
hasReadRestrictedAccessPermission({
impersonationId,
user: this.request.user
}) ||
isRestrictedView(this.request.user)
) {
const maxDividend = dividends.reduce(
(investment, item) => Math.max(investment, item.investment),
@ -328,12 +328,6 @@ export class PortfolioController {
@Query('range') dateRange: DateRange = 'max',
@Query('tags') filterByTags?: string
): Promise<PortfolioInvestments> {
const hasReadRestrictedAccessPermission =
this.userHelperService.hasReadRestrictedAccessPermission({
impersonationId,
user: this.request.user
});
const filters = this.apiService.buildFiltersFromQueryParams({
filterByAccounts,
filterByAssetClasses,
@ -349,8 +343,11 @@ export class PortfolioController {
});
if (
hasReadRestrictedAccessPermission ||
this.userHelperService.isRestrictedView(this.request.user)
hasReadRestrictedAccessPermission({
impersonationId,
user: this.request.user
}) ||
isRestrictedView(this.request.user)
) {
const maxInvestment = investments.reduce(
(investment, item) => Math.max(investment, item.investment),
@ -399,12 +396,6 @@ export class PortfolioController {
): Promise<PortfolioPerformanceResponse> {
const withExcludedAccounts = withExcludedAccountsParam === 'true';
const hasReadRestrictedAccessPermission =
this.userHelperService.hasReadRestrictedAccessPermission({
impersonationId,
user: this.request.user
});
const filters = this.apiService.buildFiltersFromQueryParams({
filterByAccounts,
filterByAssetClasses,
@ -420,9 +411,12 @@ export class PortfolioController {
});
if (
hasReadRestrictedAccessPermission ||
this.request.user.Settings.settings.viewMode === 'ZEN' ||
this.userHelperService.isRestrictedView(this.request.user)
hasReadRestrictedAccessPermission({
impersonationId,
user: this.request.user
}) ||
isRestrictedView(this.request.user) ||
this.request.user.Settings.settings.viewMode === 'ZEN'
) {
performanceInformation.chart = performanceInformation.chart.map(
({

19
apps/api/src/interceptors/redact-values-in-response/redact-values-in-response.interceptor.ts

@ -1,6 +1,9 @@
import { redactAttributes } from '@ghostfolio/api/helper/object.helper';
import { UserHelperService } from '@ghostfolio/api/services/user-helper/user-helper.service';
import { HEADER_KEY_IMPERSONATION } from '@ghostfolio/common/config';
import {
hasReadRestrictedAccessPermission,
isRestrictedView
} from '@ghostfolio/common/permissions';
import { UserWithSettings } from '@ghostfolio/common/types';
import {
@ -16,7 +19,7 @@ import { map } from 'rxjs/operators';
export class RedactValuesInResponseInterceptor<T>
implements NestInterceptor<T, any>
{
public constructor(private userHelperService: UserHelperService) {}
public constructor() {}
public intercept(
context: ExecutionContext,
@ -29,15 +32,13 @@ export class RedactValuesInResponseInterceptor<T>
const impersonationId =
headers?.[HEADER_KEY_IMPERSONATION.toLowerCase()];
const hasReadRestrictedPermission =
this.userHelperService.hasReadRestrictedAccessPermission({
impersonationId,
user
});
if (
hasReadRestrictedPermission ||
this.userHelperService.isRestrictedView(user)
hasReadRestrictedAccessPermission({
impersonationId,
user
}) ||
isRestrictedView(user)
) {
data = redactAttributes({
object: data,

9
apps/api/src/interceptors/redact-values-in-response/redact-values-in-response.module.ts

@ -1,11 +1,4 @@
import { UserHelperModule } from '@ghostfolio/api/services/user-helper/user-helper.module';
import { UserHelperService } from '@ghostfolio/api/services/user-helper/user-helper.service';
import { Module } from '@nestjs/common';
@Module({
exports: [UserHelperService],
imports: [UserHelperModule],
providers: [UserHelperService]
})
@Module({})
export class RedactValuesInResponseModule {}

9
apps/api/src/services/user-helper/user-helper.module.ts

@ -1,9 +0,0 @@
import { Module } from '@nestjs/common';
import { UserHelperService } from './user-helper.service';
@Module({
exports: [UserHelperService],
providers: [UserHelperService]
})
export class UserHelperModule {}

30
apps/api/src/services/user-helper/user-helper.service.ts

@ -1,30 +0,0 @@
import { UserWithSettings } from '@ghostfolio/common/types';
import { Injectable } from '@nestjs/common';
@Injectable()
export class UserHelperService {
public constructor() {}
public hasReadRestrictedAccessPermission({
impersonationId,
user
}: {
impersonationId: string;
user: UserWithSettings;
}) {
if (!impersonationId) {
return false;
}
const access = user.Access?.find(({ id }) => {
return id === impersonationId;
});
return access?.permissions?.includes('READ_RESTRICTED') ?? true;
}
public isRestrictedView(aUser: UserWithSettings) {
return aUser.Settings.settings.isRestrictedView ?? false;
}
}

24
libs/common/src/lib/permissions.ts

@ -125,6 +125,28 @@ export function hasPermission(
return aPermissions.includes(aPermission);
}
export function hasRole(aUser: UserWithSettings, aRole: Role): boolean {
export function hasReadRestrictedAccessPermission({
impersonationId,
user
}: {
impersonationId: string;
user: UserWithSettings;
}) {
if (!impersonationId) {
return false;
}
const access = user.Access?.find(({ id }) => {
return id === impersonationId;
});
return access?.permissions?.includes('READ_RESTRICTED') ?? true;
}
export function hasRole(aUser: UserWithSettings, aRole: Role) {
return aUser?.role === aRole;
}
export function isRestrictedView(aUser: UserWithSettings) {
return aUser.Settings.settings.isRestrictedView ?? false;
}

Loading…
Cancel
Save