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

Better way to accept null values #10

Open
SylvainEstevez opened this issue Sep 21, 2018 · 3 comments
Open

Better way to accept null values #10

SylvainEstevez opened this issue Sep 21, 2018 · 3 comments

Comments

@SylvainEstevez
Copy link
Collaborator

We currently use the AWS way of handling null values in permission conditions (see https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_condition_operators.html#Conditions_Null).

While this provides the expected functionality, it forces the consumers to duplicate their permissions in cases where null is one of the accepted values in addition to another type.

{
    id: 'WithString',
    condition: {
        stringEquals: {
            simpleValue: { foo: 'bar' }
        }
    }
}


{
    id: 'WithNull',
    condition: {
        null: {
            simpleValue: { foo: 'true' }
        }
    }
}

Instead, we would like to find a more elegant solution that would consumers to express the previous 2 conditions as a single "string OR null" statement.

@lazharichir
Copy link

Hello @SylvainEstevez — just wondering if you settled on a path to doing this? Thank you!

@SylvainEstevez
Copy link
Collaborator Author

Hey @lazharichir, thanks for reaching out. No plan to support "OR" statements at the moment. If you have a syntax proposal, I'd be happy to look at it! But my guess is that it's going to complexify the syntax a lot :/

As a workaround, here is a quick and dirty factory you could get inspiration from in order to avoid code duplication:

import { TPermission, Keys, PermissionEffect } from "@bluejay/access-control";
import { cloneDeep, merge } from 'lodash';

/**
 *
 *
 * @param permission
 * @param conditionPath
 */
const makePropertyNullable = (permission: TPermission, conditionPath: string): TPermission => {
  // Get the property name.
  const nullableProperty = conditionPath.split('.')[2];

  // Create a cloned version of the permission without the target property.
  const filteredPermission = Keys.filter(cloneDeep(permission), `!condition.${conditionPath}`) as TPermission;

  // Finally add the nullable condition.
  return merge(filteredPermission, <Pick<TPermission, 'id' | 'condition'>>{
    id: `${permission.id}_WithNullable_${nullableProperty}`, // `id` needs to be unique.
    condition: {
      null: {
        simpleValue: {
          [nullableProperty]: 'true'
        }
      }
    }
  });
}


const original: TPermission = {
  id: 'FooBar',
  effect: PermissionEffect.ALLOW,
  resource: 'foo',
  action: 'bar',
  condition: {
    stringEquals: {
      simpleValue: {
        aProperty: 'aValue'
      }
    }
  }
};


const withNullableProperty = makePropertyNullable(original, 'stringEquals.simpleValue.aProperty');

Which produces:

{
  "id": "FooBar_WithNullable_aProperty",
  "effect": "allow",
  "resource": "foo",
  "action": "bar",
  "condition": {
    "null": {
      "simpleValue": {
        "aProperty": "true"
      }
    }
  }
}

Hope that helps!

@lazharichir
Copy link

lazharichir commented Apr 29, 2020 via email

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

2 participants