Files
ubicloud/lib/access_policy_converter.rb
Jeremy Evans b05669f677 Add a converter from access policy entries to access control entries
A project can have multiple access policies, and each access policy
can have multiple entries.  Each entry in an access policy can
convert into an access control entry.  If there are multiple
subjects, actions, or objects in the access policy entry, a tag
can be created for each, and that tag can be used in the access
control entry.

This breaks the process down into three separate methods:

* parse_access_policy_rows: parses the access_policy table rows
  into arrays of uuids, one for each access control entry.  The
  subject, action, and object entries in each array can themselves
  be arrays of uuids. Also populates :admin and :member keys for
  projects.  These keys will be used to populate the Admin and
  Member subject tags for the projects.

* convert_access_policy_rows: calls parse_access_policy_rows,
  and further converts the entries, returning an unsaved
  AccessControlEntry for each.  The subject_id, action_id, and
  object_id values, if they need to be tags, are arrays, with the
  unsaved tag as the first element, and an array of checked member
  uuids as the second element.  This removes the :admin and :member
  keys and uses them to populate the unsaved Admin and Member subject
  tags. Admin and Member subject tags will be created even if they
  would be empty, though empty Admin subject tags will be added to
  the failures_array.

* save_converted_access_policy_rows: calls convert_access_policy_rows,
  and saves each access control entry.  If the access control entry
  references tags, saves the tags first.

For all three methods, they return a hash with :projects and :failures
keys.  The :projects value is a hash with :aces values described above.
The :failures key is an array of arrays of failure information, which
can be used for debugging.

If the AccessPolicy body has only a single entry, and all
actions are allowed, treat it as admin.  This is not perfect, as
projects can have multiple AccessPolicies, and one could have one entry
that allows all actions to a subset of objects, with the intention being
no access to other objects.  However, the vast majority of projects do
not have admin managed policies, so there needs to be a way to convert
non-managed admin-style policies to members of the generated Admin
subject tags.

Treat users with Project:policy action as admins.  This action is not
used, but was used by default at some point in the past.  If the user
could modify the policy, they are de facto an admin of the system, since
they could modify the policy to grant any action they needed.

If there is no project admin, but only a single account associated with
the project, make that account the project admin.

Do not use an exact match for member policies, because the
InferenceEndpoint:view was recently added for new policies, but existing
policies were not updated for it.

For ApiKey subjects, include them in the admin tag, but do not allow
the to be in other tags.  Convert them from being in other tags to
having separate ACEs just for the APIKey.

For subjects with admin access, do not create separate ACEs just for
them, since they don't need it if they have admin access.  This mostly
affects APIKeys, since those have individual APIKey entries, though
it could affect Accounts as well.

Ignore soft-deleted projects and projects without accounts when doing
the conversion.

No specs for this, it will only be used once to convert access policies
to access control entries.
2025-01-06 08:55:23 -08:00

7.8 KiB