Skip to content

Commit

Permalink
Feature/check api acces (#250)
Browse files Browse the repository at this point in the history
* Partial done access check

* get users on allowed organizations instead of all users.

---------

Co-authored-by: Frederik Christ Vestergaard <[email protected]>
Co-authored-by: August Andersen <[email protected]>
  • Loading branch information
3 people authored May 13, 2024
1 parent 1a03b5d commit 5cfa8ee
Show file tree
Hide file tree
Showing 8 changed files with 93 additions and 7,688 deletions.
7,549 changes: 1 addition & 7,548 deletions package-lock.json

Large diffs are not rendered by default.

5 changes: 4 additions & 1 deletion src/controllers/user-management/organization.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,14 @@ import { AuditLog } from "@services/audit-log.service";
import { ActionType } from "@entities/audit-log-entry";
import { ListAllEntitiesDto } from "@dto/list-all-entities.dto";
import { ApiAuth } from "@auth/swagger-auth-decorator";
import { checkIfUserHasAccessToOrganization, OrganizationAccessScope } from "@helpers/security-helper";
import { PermissionType } from "@enum/permission-type.enum";

@UseGuards(JwtAuthGuard, RolesGuard)
@ApiAuth()
@ApiForbiddenResponse()
@ApiUnauthorizedResponse()
@ApiTags("User Management")
@ApiTags("Organization")
@Controller("organization")
@GlobalAdmin()
export class OrganizationController {
Expand Down Expand Up @@ -121,6 +123,7 @@ export class OrganizationController {
@Param("id", new ParseIntPipe()) id: number
): Promise<Organization> {
try {
checkIfUserHasAccessToOrganization(req, id, OrganizationAccessScope.UserAdministrationRead);
return await this.organizationService.findByIdWithRelations(id);
} catch (err) {
throw new NotFoundException(ErrorCodes.IdDoesNotExists);
Expand Down
2 changes: 1 addition & 1 deletion src/controllers/user-management/permission.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ import { ApiAuth } from "@auth/swagger-auth-decorator";
@ApiAuth()
@ApiForbiddenResponse()
@ApiUnauthorizedResponse()
@ApiTags("User Management")
@ApiTags("Permission")
@Controller("permission")
export class PermissionController {
constructor(
Expand Down
12 changes: 10 additions & 2 deletions src/controllers/user-management/user.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,15 @@ export class UserController {

@Get()
@ApiOperation({ summary: "Get all users" })
async findAll(@Query() query?: ListAllEntitiesDto): Promise<ListAllUsersResponseDto> {
return await this.userService.findAll(query);
async findAll(
@Req() req: AuthenticatedRequest,
@Query() query?: ListAllEntitiesDto
): Promise<ListAllUsersResponseDto> {
if (req.user.permissions.isGlobalAdmin) {
return await this.userService.findAll(query);
} else {
const allowedOrganizations = req.user.permissions.getAllOrganizationsWithUserAdmin();
return await this.userService.getUsersOnOrganizations(allowedOrganizations, query);
}
}
}
14 changes: 2 additions & 12 deletions src/entities/dto/list-all-applications.dto.ts
Original file line number Diff line number Diff line change
@@ -1,26 +1,16 @@
import { DefaultLimit, DefaultOffset } from "@config/constants/pagination-constants";
import { ListAllEntitiesDto } from "@dto/list-all-entities.dto";
import { IsSwaggerOptional } from "@helpers/optional-validator";
import {
NullableStringToNumber,
StringToNumber,
} from "@helpers/string-to-number-validator";
import { NullableStringToNumber, StringToNumber } from "@helpers/string-to-number-validator";
import { ApiProperty, OmitType } from "@nestjs/swagger";
import { Transform } from "class-transformer";
import { IsOptional, IsNumber } from "class-validator";

export class ListAllApplicationsDto extends OmitType(ListAllEntitiesDto, [
"limit",
"offset",
]) {
export class ListAllApplicationsDto extends OmitType(ListAllEntitiesDto, ["limit", "offset"]) {
@IsSwaggerOptional({ description: "Filter to one organization" })
@StringToNumber()
organizationId?: number;

@IsSwaggerOptional({ description: "Filter to one permission" })
@StringToNumber()
permissionId?: number;

@ApiProperty({ type: Number, required: false })
@IsOptional()
@IsNumber()
Expand Down
2 changes: 1 addition & 1 deletion src/services/device-management/application.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -427,7 +427,7 @@ export class ApplicationService {
name: device.name,
type: device.type,
latestSentMessage: device.latestReceivedMessage?.sentTime,
location: device.location
location: device.location,
};
});

Expand Down
51 changes: 13 additions & 38 deletions src/services/user-management/organization.service.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,4 @@
import {
BadRequestException,
Inject,
Injectable,
Logger,
forwardRef,
NotFoundException,
} from "@nestjs/common";
import { BadRequestException, Inject, Injectable, Logger, forwardRef, NotFoundException } from "@nestjs/common";
import { InjectRepository } from "@nestjs/typeorm";
import { In, Repository } from "typeorm";

Expand All @@ -24,6 +17,7 @@ import { PermissionService } from "./permission.service";
import { User } from "@entities/user.entity";
import { UserService } from "./user.service";
import { Permission } from "@entities/permissions/permission.entity";
import { AuthenticatedRequest } from "@dto/internal/authenticated-request";

@Injectable()
export class OrganizationService {
Expand Down Expand Up @@ -55,22 +49,15 @@ export class OrganizationService {
}
}

async update(
id: number,
dto: UpdateOrganizationDto,
userId: number
): Promise<Organization> {
async update(id: number, dto: UpdateOrganizationDto, userId: number): Promise<Organization> {
const org = await this.findByIdWithRelations(id);
org.name = dto.name;
org.updatedBy = userId;

return await this.organizationRepository.save(org);
}

async updateOpenDataDkRegistered(
id: number,
userId: number
): Promise<Organization> {
async updateOpenDataDkRegistered(id: number, userId: number): Promise<Organization> {
const org = await this.findByIdWithRelations(id);
org.openDataDkRegistered = true;
org.updatedBy = userId;
Expand All @@ -84,14 +71,9 @@ export class OrganizationService {
return await this.organizationRepository.save(org);
}

async rejectAwaitingUser(
user: User,
organization: Organization
): Promise<Organization> {
async rejectAwaitingUser(user: User, organization: Organization): Promise<Organization> {
if (organization.awaitingUsers.find(dbUser => dbUser.id === user.id)) {
const index = organization.awaitingUsers.findIndex(
dbUser => dbUser.id === user.id
);
const index = organization.awaitingUsers.findIndex(dbUser => dbUser.id === user.id);
organization.awaitingUsers.splice(index, 1);
await this.userService.sendRejectionMail(user, organization);
return await this.organizationRepository.save(organization);
Expand All @@ -110,9 +92,7 @@ export class OrganizationService {
};
}

mapPermissionsToOrganizations(
permissions: Permission[]
): Organization[] {
mapPermissionsToOrganizations(permissions: Permission[]): Organization[] {
const requestedOrganizations: Organization[] = [];

for (let index = 0; index < permissions.length; index++) {
Expand Down Expand Up @@ -141,14 +121,12 @@ export class OrganizationService {
return requestedOrganizations;
}

mapPermissionsToOneOrganization(
permissions: Permission[]
): Organization {
mapPermissionsToOneOrganization(permissions: Permission[]): Organization {
const org: Organization = new Organization();

permissions.map(permission => {
org.id = permission.organization.id;
org.name = permission.organization.name
org.name = permission.organization.name;
});

org.permissions = [];
Expand All @@ -163,9 +141,7 @@ export class OrganizationService {
return org;
}

async findAllPaginated(
query?: ListAllEntitiesDto
): Promise<ListAllOrganizationsResponseDto> {
async findAllPaginated(query?: ListAllEntitiesDto): Promise<ListAllOrganizationsResponseDto> {
const sorting: { [id: string]: string | number } = this.getSorting(query);

const [data, count] = await this.organizationRepository.findAndCount({
Expand All @@ -182,6 +158,7 @@ export class OrganizationService {
}

async findAllMinimal(): Promise<ListAllMinimalOrganizationsResponseDto> {

const [data, count] = await this.organizationRepository.findAndCount({
select: ["id", "name"],
});
Expand Down Expand Up @@ -218,9 +195,7 @@ export class OrganizationService {
const sorting: { [id: string]: string | number } = {};
if (
query?.orderOn != null &&
(query.orderOn == "id" ||
query.orderOn == "name" ||
query.orderOn == "lastLogin")
(query.orderOn == "id" || query.orderOn == "name" || query.orderOn == "lastLogin")
) {
sorting[query.orderOn] = query.sort.toLocaleUpperCase();
} else {
Expand All @@ -230,7 +205,7 @@ export class OrganizationService {
}

async findById(organizationId: number): Promise<Organization> {
return await this.organizationRepository.findOneByOrFail({ id: organizationId});
return await this.organizationRepository.findOneByOrFail({ id: organizationId });
}

async findByIdWithRelations(organizationId: number): Promise<Organization> {
Expand Down
Loading

0 comments on commit 5cfa8ee

Please sign in to comment.