Skip to content

Commit

Permalink
Merge pull request #1394 from SciCatProject/fix-user-identities-isval…
Browse files Browse the repository at this point in the history
…idemail-access

fix: fixed permissions on user identities and improved swagger documentation
  • Loading branch information
nitrosx authored Aug 26, 2024
2 parents 213d0df + d48a288 commit 6477260
Show file tree
Hide file tree
Showing 2 changed files with 93 additions and 7 deletions.
24 changes: 24 additions & 0 deletions src/common/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -925,6 +925,30 @@ export const samplesFullQueryDescriptionFields =
}\n \
</pre>';

export const filterUserIdentityExample =
'{ "profile.email": "[email protected]" }';

export const filterUserIdentityDescription =
'<pre>\n \
[email protected]\n \
or \n \
{\n \
"email": "[email protected]"\n \
}\n \
or \n \
{\n \
"profile.email": "[email protected]"\n \
}\n \
or \n \
{\n \
"where?": {\n \
"profile.email": "[email protected]"\n \
}\n \
}\n \
This last version is deprecated and will be discontinued as soon as the FE is updated.\n \
It has been maintanined for backward compatibility.\n \
</pre>';

export const parseBoolean = (v: unknown): boolean => {
switch (v) {
case true:
Expand Down
76 changes: 69 additions & 7 deletions src/users/user-identities.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,13 @@ import {
Req,
UseGuards,
} from "@nestjs/common";
import { ApiBearerAuth, ApiTags } from "@nestjs/swagger";
import {
ApiBearerAuth,
ApiOperation,
ApiQuery,
ApiResponse,
ApiTags,
} from "@nestjs/swagger";
import { Action } from "src/casl/action.enum";
import { AppAbility, CaslAbilityFactory } from "src/casl/casl-ability.factory";
import { CheckPolicies } from "src/casl/decorators/check-policies.decorator";
Expand All @@ -18,6 +24,11 @@ import { Request } from "express";
import { JWTUser } from "src/auth/interfaces/jwt-user.interface";
import { User } from "./schemas/user.schema";
import { AuthenticatedPoliciesGuard } from "../casl/guards/auth-check.guard";
import { boolean } from "mathjs";
import {
filterUserIdentityDescription,
filterUserIdentityExample,
} from "src/common/utils";

@ApiBearerAuth()
@ApiTags("user identities")
Expand All @@ -36,6 +47,27 @@ export class UserIdentitiesController {
ability.can(Action.UserReadAny, User),
)
@Get("/findOne")
@ApiOperation({
summary:
"It returns the user identity profile of the first user matching the query",
description:
"This endpoint returns the user identity profile of the first user matching teh condition",
})
@ApiQuery({
name: "filter",
description:
"Full database filters to apply when checking for the email. The filter can be just the where clause or the full filter syntax\n" +
filterUserIdentityDescription,
required: false,
type: String,
example: filterUserIdentityExample,
})
@ApiResponse({
status: 201,
type: boolean,
description:
"Results is true if a registered user exists that have the emailed provided listed as main email",
})
async findOne(
// NOTE: This now supports both headers filter and query filter.
// There is a loopback config file where we have this as a setting on the frontend.
Expand Down Expand Up @@ -89,15 +121,49 @@ export class UserIdentitiesController {
}

@UseGuards(AuthenticatedPoliciesGuard)
@CheckPolicies("users", (ability: AppAbility) =>
ability.can(Action.UserReadAny, User),
)
@Get("/isValidEmail")
@ApiOperation({
summary:
"It returns true if the emailed passed in is linked to any registered users",
description:
"This endpoint check if the email passed in as parameter is a valid email connected to a known user that has a record in this instance of SciCat",
})
@ApiQuery({
name: "filter",
description:
"Email to be checked or full filter format query to apply when checking for the email\n" +
filterUserIdentityDescription,
required: false,
type: String,
example: filterUserIdentityExample,
})
@ApiResponse({
status: 201,
type: boolean,
description:
"Results is true if a registered user exists that have the emailed provided listed as main email",
})
async isValidEmail(
// NOTE: This now supports both headers filter and query filter.
// There is a loopback config file where we have this as a setting on the frontend.
// In the future if we fully migrate to the new backend we can only support query filters.
@Headers() headers: Record<string, string>,
@Query("filter") queryFilters?: string,
): Promise<boolean | null> {
const parsedQueryFilters = JSON.parse(queryFilters ?? "{}");
let parsedQueryFilters;
try {
parsedQueryFilters = JSON.parse(queryFilters ?? "{}");
} catch {
parsedQueryFilters = {
where: {
"profile.email": queryFilters,
},
};
}

let filter = {};
if (headers.filter) {
const parsedFilter = JSON.parse(headers.filter);
Expand All @@ -112,10 +178,6 @@ export class UserIdentitiesController {
filter,
)) as UserIdentity;

if (!identity) {
return false;
}

return true;
return identity ? true : false;
}
}

0 comments on commit 6477260

Please sign in to comment.