Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feature request: UnwrapCaslSubjectPipe #202

Open
ruscon opened this issue Dec 15, 2021 · 3 comments
Open

feature request: UnwrapCaslSubjectPipe #202

ruscon opened this issue Dec 15, 2021 · 3 comments
Milestone

Comments

@ruscon
Copy link
Contributor

ruscon commented Dec 15, 2021

If you want to get subject from hook into a class method argument, you need to use SubjectProxy and manually get the subject (example from docs)

@Mutation(() => Post)
@UseGuards(AuthGuard, AccessGuard)
@UseAbility(Actions.update, Post, PostHook)
async updatePost(
  @Args('input') input: UpdatePostInput,
  @CaslSubject() subjectProxy: SubjectProxy<Post>
) {
  const post = await subjectProxy.get();
}

This can be automated through a generic pipe

import { Injectable, NotFoundException, PipeTransform } from '@nestjs/common';
import type { SubjectProxy } from 'nest-casl';

@Injectable()
export class UnwrapCaslSubjectPipe<T> implements PipeTransform<SubjectProxy<T>, Promise<T>> {
    async transform(subjectProxy: SubjectProxy<T>): Promise<T> {
        const subject = await subjectProxy.get();

        if (!subject) {
            throw new NotFoundException();
        }

        return subject;
    }
}

And code will be like this

@Mutation(() => Post)
@UseGuards(AuthGuard, AccessGuard)
@UseAbility(Actions.update, Post, PostHook)
async updatePost(
  @Args('input') input: UpdatePostInput,
  @CaslSubject(UnwrapCaslSubjectPipe) post: Post,
) {
  // do anything with post oject
}
@liquidautumn
Copy link
Collaborator

I looked desperately to hide proxy details and never found this solution. Would be so nice to implicitly unwrap proxy, but API already published. Maybe add Subject and alike decorators and deprecate prefixed ones. Anyway, this is super useful, I'll think how to best handle it and add asap.

@ruscon
Copy link
Contributor Author

ruscon commented Dec 22, 2021

There is no BC in my example :)
Just need to add UnwrapCaslSubjectPipe to your library (@CaslSubject works with pipes)

@liquidautumn liquidautumn added this to the Milestone 0 milestone Oct 31, 2022
@AlexStansfield
Copy link

I'd be interested in something like this.

Basically right now whenever there is an ID for a resource in the parameters we use a transformer pipe so that fetch the resource, error if not found and then have it delievered into the controller method argument.

e.g

  @Get(':id')
  @UseGuards(AccessGuard)
  @UseAbility(Actions.read, ProductDto)
  @ApiOkResponse({ type: ProductDto })
  getProduct(@Param('id', ProductTransformerPipe) product: IProduct): IProduct {
    return product;
  }

Would love a way that Casl could use this object as the subject. Any ideas?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants