Skip to content
Open
Show file tree
Hide file tree
Changes from 12 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 19 additions & 13 deletions api-gateway/src/api/service/permissions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -416,8 +416,8 @@ export class PermissionsApi {
role,
status,
username,
did: { $ne: user.did }
},
currentUsername: user.username,
parent: user.parent ? user.parent : user.did,
pageIndex,
pageSize
Expand Down Expand Up @@ -470,8 +470,10 @@ export class PermissionsApi {
try {
const owner = user.parent || user.did;
const users = new Users();
const row = await users.getUserPermissions(username, user.id);
if (!row || row.parent !== owner || row.did === user.did) {

const row = await users.getUserPermissions(username, owner, user.id);

if (!row || row.did === user.did) {
throw new HttpException('User does not exist.', HttpStatus.NOT_FOUND);
}
return row as any;
Expand Down Expand Up @@ -528,11 +530,12 @@ export class PermissionsApi {
let row: any;
const users = new Users();
try {
row = await users.getUserPermissions(username, user.id);
const parent = user.parent || user.did;
row = await users.getUserPermissions(username, parent, user.id);
} catch (error) {
await InternalException(error, this.logger, user.id);
}
if (!row || row.parent !== user.did || row.did === user.did) {
if (!row || row.did === user.did) {
throw new HttpException('User does not exist.', HttpStatus.NOT_FOUND)
}
try {
Expand Down Expand Up @@ -618,11 +621,11 @@ export class PermissionsApi {
const owner = user.parent || user.did;
let target: any;
try {
target = await (new Users()).getUserPermissions(username, user.id);
target = await (new Users()).getUserPermissions(username, owner, user.id);
} catch (error) {
await InternalException(error, this.logger, user.id);
}
if (!target || target.parent !== owner) {
if (!target) {
throw new HttpException('User does not exist.', HttpStatus.NOT_FOUND)
}
try {
Expand Down Expand Up @@ -684,11 +687,12 @@ export class PermissionsApi {
let row: any;
const users = new Users();
try {
row = await users.getUserPermissions(username, user.id);
const parent = user.parent || user.did;
row = await users.getUserPermissions(username, parent, user.id);
} catch (error) {
await InternalException(error, this.logger, user.id);
}
if (!row || row.parent !== user.did || row.did === user.did) {
if (!row || row.did === user.did) {
throw new HttpException('User does not exist.', HttpStatus.NOT_FOUND)
}
try {
Expand Down Expand Up @@ -750,11 +754,12 @@ export class PermissionsApi {
let row: any;
const users = new Users();
try {
row = await users.getUserPermissions(username, user.id);
const parent = user.parent || user.did;
row = await users.getUserPermissions(username, parent, user.id);
} catch (error) {
await InternalException(error, this.logger, user.id);
}
if (!row || row.parent !== user.parent || row.did === user.did) {
if (!row || row.did === user.did) {
throw new HttpException('User does not exist.', HttpStatus.NOT_FOUND)
}
try {
Expand Down Expand Up @@ -810,11 +815,12 @@ export class PermissionsApi {
let row: any;
const users = new Users();
try {
row = await users.getUserPermissions(username, user.id);
const parent = user.parent || user.did;
row = await users.getUserPermissions(username, parent, user.id);
} catch (error) {
await InternalException(error, this.logger, user.id);
}
if (!row || row.parent !== user.parent || row.did === user.did) {
if (!row || row.did === user.did) {
throw new HttpException('User does not exist.', HttpStatus.NOT_FOUND)
}
try {
Expand Down
101 changes: 100 additions & 1 deletion api-gateway/src/api/service/profile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { Permissions, TaskAction } from '@guardian/interfaces';
import { IAuthUser, PinoLogger, RunFunctionAsync } from '@guardian/common';
import { Body, Controller, Get, HttpCode, HttpException, HttpStatus, Param, Post, Put, Req, Response, Query, Delete } from '@nestjs/common';
import { ApiBody, ApiExtraModels, ApiInternalServerErrorResponse, ApiOkResponse, ApiOperation, ApiParam, ApiQuery, ApiTags } from '@nestjs/swagger';
import { CredentialsDTO, DidDocumentDTO, DidDocumentStatusDTO, DidDocumentWithKeyDTO, DidKeyStatusDTO, Examples, InternalServerErrorDTO, PolicyKeyConfigDTO, PolicyKeyDTO, ProfileDTO, TaskDTO, pageHeader } from '#middlewares';
import { CredentialsDTO, DidDocumentDTO, DidDocumentStatusDTO, DidDocumentWithKeyDTO, DidKeyStatusDTO, Examples, InternalServerErrorDTO, PolicyKeyConfigDTO, PolicyKeyDTO, ProfileDTO, TaskDTO, pageHeader, UserDidDTO } from '#middlewares';
import { Auth, AuthUser } from '#auth';
import { CacheService, getCacheKey, Guardians, InternalException, ServiceError, TaskManager, UseCache } from '#helpers';
import { CACHE, PREFIXES } from '#constants';
Expand Down Expand Up @@ -104,6 +104,105 @@ export class ProfileApi {
await this.cacheService.invalidate(getCacheKey([req.url, ...invalidedCacheTags], user))
}

/**
* Update user parent
*/
@Put('/parent/select/:username')
@Auth(
//Permissions.PROFILES_USER_UPDATE,
)
@ApiOperation({
summary: '',
description: ''
})
@ApiParam({
name: 'username',
type: String,
description: 'The name of the user for whom to update the information.',
required: true,
example: 'username'
})
@ApiBody({
description: '',
required: true,
type: UserDidDTO
})
@ApiOkResponse({
description: 'Updated.',
})
@ApiInternalServerErrorResponse({
description: 'Internal server error.',
type: InternalServerErrorDTO
})
@ApiExtraModels(UserDidDTO, InternalServerErrorDTO)
@HttpCode(HttpStatus.NO_CONTENT)
async setUserStandardRegistry(
@AuthUser() user: IAuthUser,
@Body() parent: any,
@Req() req
): Promise<void> {
const { username } = user;
const guardians = new Guardians();
try {
await guardians.updateUserStandardRegistry(username, parent.did);

const invalidedCacheTags = [`/${PREFIXES.PROFILES}/${user.username}`];

await this.cacheService.invalidate(getCacheKey([req.url, ...invalidedCacheTags], user))
} catch (error) {
throw new HttpException(error.message, HttpStatus.UNAUTHORIZED);
}
}

/**
* Add user standart registry
*/
@Put('/parent/add/:username')
@Auth(
//Permissions.PROFILES_USER_UPDATE,
)
@ApiOperation({
summary: '',
description: ''
})
@ApiParam({
name: 'username',
type: String,
description: 'The name of the user for whom to update the information.',
required: true,
example: 'username'
})
@ApiBody({
description: '',
required: true,
type: UserDidDTO
})
@ApiOkResponse({
description: 'Updated.',
})
@ApiInternalServerErrorResponse({
description: 'Internal server error.',
type: InternalServerErrorDTO
})
@ApiExtraModels(UserDidDTO, InternalServerErrorDTO)
@HttpCode(HttpStatus.NO_CONTENT)
async addUserStandardRegistry(
@AuthUser() user: IAuthUser,
@Body() parent: any,
@Req() req
): Promise<void> {
const guardians = new Guardians();
try {
await guardians.addUserStandardRegistry(user, user.username, parent.did);

const invalidedCacheTags = [`/${PREFIXES.PROFILES}/${user.username}`];

await this.cacheService.invalidate(getCacheKey([req.url, ...invalidedCacheTags], user))
} catch (error) {
throw new HttpException(error.message, HttpStatus.UNAUTHORIZED);
}
}

/**
* Update user profile (async)
*/
Expand Down
18 changes: 18 additions & 0 deletions api-gateway/src/helpers/guardians.ts
Original file line number Diff line number Diff line change
Expand Up @@ -491,6 +491,24 @@ export class Guardians extends NatsService {
return await this.sendMessage(MessageAPI.CREATE_USER_PROFILE_COMMON, { user, username, profile });
}

/**
* Update standart registry
* @param username
* @param standartRegistryDid
*/
public async updateUserStandardRegistry(username: string, standardRegistryDid: string): Promise<string> {
return await this.sendMessage(MessageAPI.USER_UPDATE_STANDARD_REGISTRY, { username, standardRegistryDid });
}

/**
* Update standart registry
* @param username
* @param standartRegistryDid
*/
public async addUserStandardRegistry(user: IAuthUser, username: string, standardRegistryDids: string[]): Promise<string> {
return await this.sendMessage(MessageAPI.USER_ADD_STANDARD_REGISTRY, { user, username, standardRegistryDids });
}

/**
* Async create user
* @param username
Expand Down
6 changes: 3 additions & 3 deletions api-gateway/src/helpers/users.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,8 @@ export class Users extends NatsService {
* @param username
* @param userId
*/
public async getUserPermissions(username: string, userId: string | null): Promise<IAuthUser> {
return await this.sendMessage(AuthEvents.GET_USER_PERMISSIONS, { username, userId });
public async getUserPermissions(username: string, parent: string, userId: string | null): Promise<IAuthUser> {
return await this.sendMessage(AuthEvents.GET_USER_PERMISSIONS, { username, parent, userId });
}

/**
Expand Down Expand Up @@ -514,4 +514,4 @@ export class UsersService {
public async generateNewUserTokenBasedOnExternalUserProvider(userProvider: ProviderAuthUser): Promise<any> {
return await this.users.generateNewUserTokenBasedOnExternalUserProvider(userProvider);
}
}
}
12 changes: 11 additions & 1 deletion api-gateway/src/middlewares/validation/schemas/profiles.dto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,22 @@ export class UserDTO implements IUser {
@ApiProperty({
type: 'string',
required: false,
example: Examples.DID
example: [Examples.DID]
})
@IsOptional()
@IsString()
parent?: string;

@ApiProperty({
type: 'string',
required: false,
isArray: true,
example: Examples.DID
})
@IsOptional()
@IsString()
parents?: string[];

@ApiProperty({
type: 'string',
required: false,
Expand Down
5 changes: 5 additions & 0 deletions api-gateway/src/middlewares/validation/schemas/profiles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@ export class DidKeyDTO {
key: string;
}

export class UserDidDTO {
@ApiProperty({ type: 'string', nullable: false, required: true })
did: string;
}

export class DidDocumentDTO {
@ApiProperty({ type: 'string', nullable: false, required: true })
id: string;
Expand Down
45 changes: 25 additions & 20 deletions auth-service/src/api/account-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import {
UserRole
} from '@guardian/interfaces';
import { UserUtils, UserPassword, PasswordType, UserAccessTokenService, UserProp } from '#utils';
import { ParentPermissions } from '../entity/parent-permissions.js';
import { passwordComplexity, PasswordError } from '#constants';
import { HttpStatus } from '@nestjs/common';

Expand Down Expand Up @@ -466,6 +467,7 @@ export class AccountService extends NatsService {
this.getMessages(AuthEvents.GET_USER_ACCOUNTS,
async (msg: {
filters?: any,
currentUsername?: string,
parent?: string,
pageIndex?: any,
pageSize?: any,
Expand All @@ -477,18 +479,8 @@ export class AccountService extends NatsService {
return new MessageError('Invalid load users parameter');
}

const { filters, pageIndex, pageSize, parent } = msg;
const otherOptions: any = {
fields: [
'username',
'did',
'hederaAccountId',
'role',
'permissionsGroup',
'permissions',
'template'
]
};
const { filters, currentUsername, pageIndex, pageSize, parent } = msg;
const otherOptions: any = {};
const _pageSize = parseInt(pageSize, 10);
const _pageIndex = parseInt(pageIndex, 10);
if (Number.isInteger(_pageSize) && Number.isInteger(_pageIndex)) {
Expand All @@ -504,15 +496,28 @@ export class AccountService extends NatsService {
if (filters.role) {
options['permissionsGroup.roleId'] = filters.role;
}
if (filters.username) {
options.username = { $regex: '.*' + filters.username + '.*' };
}
if (filters.did) {
options.did = filters.did;
}
options.username = {
...(filters.username && { $regex: '.*' + filters.username + '.*' }),
$ne: currentUsername
};
}
const [items, count] = await new DatabaseServer().findAndCount(ParentPermissions, options, otherOptions);
const resultUsers = [];
for (const item of items) {
const user = await new DatabaseServer().findOne(User, { username: item.username }, {
fields: [
'username',
'did',
'hederaAccountId',
'role',
'permissionsGroup',
'permissions',
'template'
]
});
resultUsers.push({ ...user, permissions: item.permissions, permissionsGroup: item.permissionsGroup });
}
const [items, count] = await new DatabaseServer().findAndCount(User, options, otherOptions);
return new MessageResponse({ items, count });
return new MessageResponse({ items: resultUsers, count });
} catch (error) {
await logger.error(error, ['GUARDIAN_SERVICE'], userId);
return new MessageError(error);
Expand Down
4 changes: 4 additions & 0 deletions auth-service/src/api/auth.interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@ export interface IAuthUser {
* Parent
*/
parent?: string;
/**
* Parents
*/
parents?: string[];
/**
* login expire date
*/
Expand Down
Loading
Loading