question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Permissions for single vs bulk search

See original GitHub issue

How would one limit the users ability to do bulk search on a collection?

An example use case:

You have user Wish Lists with some items, where the user can share individual items with others. The receiving user should be able to see some basic information about the wish list (_id, name, owner), but access should be limited to the item that was shared.

With CASL i would define

  can("crud", "wishlist", {owner : currentUser});
  can("read", "wishlist",["_id","name","owner"]);

  can("crud", "listitem", {owner : currentUser});
  can("read", "listitem", { sharedWith : currentUser });

This has the side-effect that users can bulk search all wishlists and owners, but the intent was only for them to have limited access to the specific wishlist associated with the item that was shared with them.

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Comments:9 (6 by maintainers)

github_iconTop GitHub Comments

1reaction
Victordmdbcommented, Sep 29, 2019

Hi, so sorry it skipped my mind. Heres the code :

import * as mongoose from 'mongoose'
import { AbilityBuilder } from '@casl/ability'
import { accessibleRecordsPlugin, permittedFieldsPlugin } from '@casl/mongoose'
import { pick } from 'lodash'

import { Types } from "mongoose"

mongoose.plugin(accessibleRecordsPlugin)
mongoose.plugin(permittedFieldsPlugin)

const ability = ( currentUser : string) => AbilityBuilder.define((can : Function) => {
  can("crud", "Category", { owner : currentUser });
  can("read", "Category", ["_id","name","owner"], { public : true });

  can("crud", "Product", { owner : currentUser });
  can("read", "Product", { public : true });
});

const CategorySchema = new mongoose.Schema({
  title       : String,
  owner       : String,
  public      : { type: Boolean, default: false }
});

const ProductSchema = new mongoose.Schema({
  category      : { type : Types.ObjectId, ref : 'Category', required: true },
  name      : String,
  public    : { type: Boolean, default: false }
});

const BobUser = "Bob";
const CharlesUser = "Charles";

const Category = mongoose.model('Category', CategorySchema);
const Product = mongoose.model('Product', ProductSchema);

async function main() {
  await mongoose.connect('mongodb://localhost/casl_test');

  await Promise.all([
    Category.create({
      title: 'Public Category A',
      owner: BobUser,
      public: true
    }),
    Category.create({
      title: 'Hidden Category B',
      owner: BobUser,
      public: false
    }),
    Category.create({
      title: 'Public Category C',
      owner: CharlesUser,
      public: true
    }),
    Category.create({
      title: 'Hidden Category D',
      owner: CharlesUser,
      public: false
    })
  ]);

  const PublicCategoryA = await Category.findOne({name:"Public Category A"});
  const HiddenCategoryB = await Category.findOne({name:"Hidden Category B"});

  const PublicCategoryC = await Category.findOne({name:"Public Category C"});
  const HiddenCategoryD = await Category.findOne({name:"Hidden Category D"});


  await Promise.all([
    Product.create({
      name: 'Product A1',
      category : PublicCategoryA,
      public: true
    }),
    Product.create({
      name: 'Product A2',
      category : PublicCategoryA,
      public: false
    }),
    Product.create({
      name: 'Product B1',
      category : HiddenCategoryB,
      public: true
    }),
    Product.create({
      name: 'Product B2',
      category : HiddenCategoryB,
      public: false
    }),
    Product.create({
      name: 'Product C1',
      category : PublicCategoryC,
      public: true
    }),
    Product.create({
      name: 'Product C2',
      category : PublicCategoryC,
      public: false
    }),
    Product.create({
      name: 'Product D1',
      category : HiddenCategoryD,
      public: true
    }),
    Product.create({
      name: 'Product D2',
      category : HiddenCategoryD,
      public: false
    }),
  ]);

  const currentUser = BobUser;

  // const products = await Product.accessibleBy(ability(currentUser)).find().populate("category");
  //Should contain Products A1, A2, B1, B2, C1 and D1

  const categories = await Category.accessibleBy(ability(currentUser)).find();
  //Should contain only categories A, B

  return categories.every( c => c.owner === currentUser );
}

main()
  .then(console.log)
  .catch(console.error)
  .then(() => mongoose.connection.close())

0reactions
stalniycommented, Apr 22, 2020

I close this for tidiness. Hopefully you found the right solution in your situation.

P.S.: frankly speaking I still don’t see where the issue is 😃 We discussed 3 different domains, despite the fact they are similar it’s hard to understand clearly what you have and what you want to achieve.

Read more comments on GitHub >

github_iconTop Results From Across the Web

BULK INSERT permission on a single database
Answer: It doesn't matter if the ADMINISTER BULK OPERATIONS is server-wide, the user won't be able to BULK INSERT ...
Read more >
Permissions (Database Engine) - SQL Server
Base securable Granular permissions on base securable Securable that contains bas... APPLICATION ROLE ALTER DATABASE APPLICATION ROLE CONTROL DATABASE APPLICATION ROLE VIEW DEFINITION DATABASE
Read more >
Edit user-specific permissions in bulk - Greenhouse Support
With the bulk action feature, you can edit individual user-specific permissions for a single permission level at a time.
Read more >
You do not have permission to use the bulk load statement
You can provide permission to user to fix this issue. Go to MS SQL server management and connect to db. In Object Explorer,...
Read more >
How do I enable Bulk Send for one or more users?
When a permission-controlled feature (such as Bulk Send) is enabled on an account, the related permissions are not added to all pre-existing ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found