Skip to content

[PW-2409] Policies implementation #123

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

Closed
wants to merge 27 commits into from
Closed

[PW-2409] Policies implementation #123

wants to merge 27 commits into from

Conversation

toydestroyer
Copy link
Contributor

@toydestroyer toydestroyer commented Oct 29, 2019

Refer to the issue id if any. Include the link to the issue. E.g:

ApplicationPolicy should make use of the actions assigned to a user

Describe the changes made. What does this PR changes that might be critical. If any critical decisions have been made, make sure you explain the rationale for these decisions.

Introducing new (almost) concept of Policy Actions represented by Action model on IAM service.

Action model has these attributes:

  • name represented action name and could be new, create, index, show, destroy, edit, update or * for wildcard. Action name points to actual controller action so if you have a custom one like publish you can create policy action with this name.
  • effectallow or deny. Everything is denied. deny effect more valuable than any amount of allow effects for the resource.
  • target_resource — resource represented by urn (including wildcarded ones):
    • urn:ros:iam::222222222:credential
    • urn:ros:iam::222222222:*
    • urn:ros:*
  • segment — scope of resources described by action. Points to actual scope on model. scope MUST accept user context as a parameter (user context is instance of PolicyUser object).

There's predefined scopes everything that just alias for all but with user context and owned, that initially also pointed to all and should be redefined if necessary, for example iam/user model:

  def self.owned(user_context)
    where(id: user_context.iam_user.id)
  end

Actions belongs to Policies and Policy has many Actions. IAM User has field attached_actions with all cached actions for this User, User Groups or User Roles. Combined and deduplicated*.

[
  {
    "name": "*",
    "effect": "allow",
    "segment": "everything",
    "resources": [
      "urn:perx:cognito::222222222:*",
      "urn:perx:comm::222222222:*",
      "urn:perx:iam::platform:tenant",
      "urn:perx:iam::222222222:*"
    ]
  }
]

How does the implementation addresses the problem

User can manage policies and actions now to set permissions for User, Group and Role.

@toydestroyer toydestroyer added the WIP Pull request still in a work in progress. Comments are welcome label Oct 29, 2019
@toydestroyer toydestroyer force-pushed the poc-policies branch 3 times, most recently from 84a48b8 to 5c53e6f Compare November 6, 2019 01:08
@toydestroyer toydestroyer changed the title Policies implementation [PW-2409] Policies implementation Nov 12, 2019
Copy link
Contributor

@rpbaltazar rpbaltazar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On going review. but first set of comments to be addressed. I'm currently looking at the URN logic that is quite complex and I believe it can be simplified.


def urn_match?(urn_to_compare)
params = %i[txt partition_name service_name region account_id resource]
record_urn = Ros::Urn.from_urn(self.class.to_urn)
record_urn = Ros::Urn.from_urn(self.to_urn)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do we need the class urn_match? method for?

check_action(:create?)
end
actions = if user.attached_actions.is_a?(String)
JSON.parse(user.attached_actions)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that this should be handled by the PolicyUser and not the ApplicationPolicy itself, meaning that once we ask the PolicyUser for its actions, we should always get the same data type back.

extend ActiveSupport::Concern

included do
scope :everything, ->(_user_context) { all }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure we should be sending the whole context to the scope. This would mean that all the models now all of the sudden know how to handle PolicyUser and know what to expect inside of it. I don't think that is the right way of doing it.
The context should most likely receive only the cognito_user_id and use it when needed, ignore it when they don't care about it

@@ -16,22 +16,24 @@ def find_by_urn(value); find_by(urn_id => value) end

# NOTE: Override in model to provide a custom id
def urn_id; :id end
end

included do
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need to have urn_match? method both in the class level and instance level?

def edit?
update?
end
actions.select! { |i| i['effect'] == 'allow' && (i['name'] == action.to_s || i['name'] == '*') }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should also probably be the responsibility of the PolicyUser instead of the application policy.
E.g.
user.can?(action, record) which returns true/false


scopes = []

actions.select! { |i| i['effect'] == 'allow' && (i['name'] == user.params['action'] || i['name'] == '*') }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could probably become

user.scopes_for?(action, scope) which would return the scopes to be sent to the original scope (line 61)

@@ -6,6 +6,8 @@ class User < Cognito::ApplicationRecord
has_many :user_pools
has_many :pools, through: :user_pools

scope :owned, ->(user_context) { where(id: user_context.cognito_user_id) }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So, as mentioned above, I don't think active records should know anything about request contexts

@@ -17,7 +17,7 @@
let(:scope) { Pundit.policy_scope!(policy_user, User) }

context 'admin iam user' do
it 'returns all users' do
xit 'returns all users' do
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we don't need these, then we can remove them

end
end
end
# RSpec.describe PolicyPolicy do
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Once again if this is not needed, then we can delete it.

@rpbaltazar
Copy link
Contributor

closing in favor of #170

@rpbaltazar rpbaltazar closed this Dec 17, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
WIP Pull request still in a work in progress. Comments are welcome
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants