diff --git a/src/casl/casl-ability.factory.ts b/src/casl/casl-ability.factory.ts index 35cd2c9ee..4bd8d1615 100644 --- a/src/casl/casl-ability.factory.ts +++ b/src/casl/casl-ability.factory.ts @@ -169,8 +169,6 @@ export class CaslAbilityFactory { can(Action.ListAll, ProposalClass); } - can(Action.Read, UserIdentity, { userId: user._id }); - can(Action.Create, UserSettings, { userId: user._id }); can(Action.Read, UserSettings, { userId: user._id }); can(Action.Update, UserSettings, { userId: user._id }); diff --git a/src/casl/guards/policies.guard.ts b/src/casl/guards/policies.guard.ts index 36d58425b..16a40fdab 100644 --- a/src/casl/guards/policies.guard.ts +++ b/src/casl/guards/policies.guard.ts @@ -18,7 +18,8 @@ export class PoliciesGuard implements CanActivate { context.getHandler(), ) || []; - const { user } = context.switchToHttp().getRequest(); + const req = context.switchToHttp().getRequest(); + const user = req.user; const ability = this.caslAbilityFactory.createForUser(user); return policyHandlers.every((handler) => diff --git a/src/users/users.controller.ts b/src/users/users.controller.ts index 080422156..e45dade0d 100644 --- a/src/users/users.controller.ts +++ b/src/users/users.controller.ts @@ -9,10 +9,11 @@ import { Delete, UseInterceptors, Put, + UnauthorizedException, } from "@nestjs/common"; import { ApiBearerAuth, ApiBody, ApiTags } from "@nestjs/swagger"; import { Action } from "src/casl/action.enum"; -import { AppAbility } from "src/casl/casl-ability.factory"; +import { AppAbility, CaslAbilityFactory } from "src/casl/casl-ability.factory"; import { CheckPolicies } from "src/casl/decorators/check-policies.decorator"; import { PoliciesGuard } from "src/casl/guards/policies.guard"; import { UserIdentity } from "./schemas/user-identity.schema"; @@ -29,6 +30,7 @@ import { CreateUserSettingsInterceptor } from "./interceptors/create-user-settin import { AuthService } from "src/auth/auth.service"; import { CredentialsDto } from "src/auth/dto/credentials.dto"; import { LocalAuthGuard } from "src/auth/guards/local-auth.guard"; +import { DatasetClass } from "src/datasets/schemas/dataset.schema"; @ApiBearerAuth() @ApiTags("users") @@ -37,6 +39,7 @@ export class UsersController { constructor( private authService: AuthService, private usersService: UsersService, + private caslAbilityFactory: CaslAbilityFactory, ) {} @AllowAny() @@ -133,4 +136,49 @@ export class UsersController { async removeSettings(@Param("id") userId: string): Promise { return this.usersService.findOneAndRemoveUserSettings(userId); } + + async checkUserAuthorization( + authenticatedUserJWT: JWTUser, + viewedUserJWT: JWTUser, + ) { + const ability = await this.caslAbilityFactory.createForUser( + authenticatedUserJWT, + ); + const viewedUser = (await this.usersService.findById( + viewedUserJWT._id, + )) as User; + const viewedUserSchema = new User(); + viewedUserSchema._id = viewedUser._id; + viewedUserSchema.id = viewedUser.id; + viewedUserSchema.realm = viewedUser.realm; + viewedUserSchema.username = viewedUser.username; + viewedUserSchema.email = viewedUser.email; + + if (!ability.can(Action.Read, viewedUserSchema)) { + throw new UnauthorizedException("Unauthorized access"); + } + } + + //@UseGuards(PoliciesGuard) + //@CheckPolicies((ability: AppAbility) => { + // console.log(ability.can(Action.Read, User)); + // return ability.can(Action.Read, User); + //}) + @AllowAny() + @Get("/:id/authorization/dataset/create") + async canUserCreateDataset( + @Req() request: Request, + @Param("id") userId: string, + ): Promise { + const authenticatedUser: JWTUser = request.user as JWTUser; + const viewedUser: JWTUser = + authenticatedUser._id !== userId + ? ((await this.usersService.findById2JWTUser(userId)) as JWTUser) + : authenticatedUser; + await this.checkUserAuthorization(authenticatedUser, viewedUser); + + const ability = await this.caslAbilityFactory.createForUser(viewedUser); + + return { authorization: ability.can(Action.Create, DatasetClass) }; + } } diff --git a/src/users/users.service.ts b/src/users/users.service.ts index 1f16efeb2..4d66851ef 100644 --- a/src/users/users.service.ts +++ b/src/users/users.service.ts @@ -188,6 +188,22 @@ export class UsersService implements OnModuleInit { return this.userModel.findById(id).exec(); } + async findById2JWTUser(id: string): Promise { + const userIdentity = await this.userIdentityModel + .findOne({ userId: id }) + .exec(); + if (userIdentity) { + const userProfile = userIdentity.profile; + return { + _id: userProfile.id, + username: userProfile.username, + email: userProfile.email, + currentGroups: userProfile.accessGroups, + } as JWTUser; + } + return null; + } + async createUserIdentity( createUserIdentityDto: CreateUserIdentityDto, ): Promise { diff --git a/test/LoginUtils.js b/test/LoginUtils.js index 22091544d..c54d0d7ad 100644 --- a/test/LoginUtils.js +++ b/test/LoginUtils.js @@ -15,6 +15,20 @@ exports.getToken = function (appUrl, user, cb) { }); }; +exports.getIdAndToken = function (appUrl, user, cb) { + request(appUrl) + .post("/api/v3/Users/Login?include=user") + .send(user) + .set("Accept", "application/json") + .end((err, res) => { + if (err) { + cb(err); + } else { + cb(res.body.userId,res.body.id); + } + }); +}; + exports.getTokenAD = function (appUrl, user, cb) { request(appUrl) .post("/auth/msad")