Skip to content

Commit

Permalink
WIP/PoC Roles support
Browse files Browse the repository at this point in the history
[noissue]

Required PR: pulp/pulpcore#1800
  • Loading branch information
mdellweg committed Jan 7, 2022
1 parent 37247d3 commit a2e1edb
Show file tree
Hide file tree
Showing 14 changed files with 386 additions and 363 deletions.
62 changes: 56 additions & 6 deletions pulp_container/app/access_policy.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
from logging import getLogger

from rest_access_policy import AccessPolicy

from pulpcore.plugin.models import AccessPolicy as AccessPolicyModel
from pulpcore.plugin.models import AccessPolicy as AccessPolicyModel, Repository
from pulpcore.plugin.access_policy import AccessPolicyFromDB

from pulp_container.app import models

_logger = getLogger(__name__)


class NamespacedAccessPolicyMixin:
"""
Expand All @@ -24,15 +28,18 @@ def has_namespace_obj_perms(self, request, view, action, permission):
namespace = obj.namespace
return request.user.has_perm(permission, namespace)
elif type(obj) == models.ContainerPushRepository:
dists_qs = models.ContainerDistribution.objects.filter(repository=obj)
for dist in dists_qs:
if request.user.has_perm(permission, dist.namespace):
for dist in obj.distributions.all():
if request.user.has_perm(permission, dist.cast().namespace):
return True
elif type(obj) == models.ContainerPushRepositoryVersion:
for dist in obj.repository.distributions.all():
if request.user.has_perm(permission, dist.cast().namespace):
return True
return False

def has_namespace_perms(self, request, view, action, permission):
"""
Check if a user has a namespace-level perms
Check if a user has a namespace-level permission
"""
ns_perm = "container.namespace_{}".format(permission.split(".", 1)[1])
base_path = request.data.get("base_path")
Expand Down Expand Up @@ -91,11 +98,54 @@ def has_namespace_model_perms(self, request, view, action):

class NamespacedAccessPolicyFromDB(AccessPolicyFromDB, NamespacedAccessPolicyMixin):
"""
Access policy for ContainerDistributionViewSet and ContainerPushRepositoryViewSet which handles
Access policy for ContainerDistributionViewSet which handles
namespace permissions.
"""


class PushRepositoryAccessPolicy(NamespacedAccessPolicyFromDB):
"""
Access policy for ContainerPushRepositoryViewSet.
"""

def has_distribution_perms(self, request, view, action, permission):
"""
Check if the user has permissions on the corresponding distribution.
Model or object permission is sufficient.
"""
if request.user.has_perm(permission):
return True
distributions = view.get_object().distributions.all()
return any(
(
request.user.has_perm(permission, distribution.cast())
for distribution in distributions
)
)


class PushRepositoryVersionAccessPolicy(NamespacedAccessPolicyFromDB):
"""
Access policy for ContainerPushRepositoryVersionViewSet.
"""

def has_distribution_perms(self, request, view, action, permission):
"""
Check if the user has permissions on the corresponding distribution.
Model or object permission is sufficient.
"""
if request.user.has_perm(permission):
return True
repository = Repository.objects.get(pk=view.kwargs["repository_pk"])
distributions = repository.distributions.all()
return any(
(
request.user.has_perm(permission, distribution.cast())
for distribution in distributions
)
)


class NamespaceAccessPolicy(AccessPolicyFromDB):
"""
Access policy for ContainerNamespaceViewSet.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Generated by Django 3.2.9 on 2021-12-10 11:51

from django.db import migrations


class Migration(migrations.Migration):

dependencies = [
('container', '0020_update_push_repo_perms'),
]

operations = [
migrations.AlterModelOptions(
name='containerdistribution',
options={'default_related_name': '%(app_label)s_%(model_name)s', 'permissions': [('pull_containerdistribution', 'Can pull from a registry repo'), ('push_containerdistribution', 'Can push into the registry repo'), ('manage_roles_containerdistribution', 'Can manage role assignments on container distribution')]},
),
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Generated by Django 3.2.9 on 2021-12-10 12:07

from django.db import migrations


class Migration(migrations.Migration):

dependencies = [
('container', '0021_alter_containerdistribution_options'),
]

operations = [
migrations.AlterModelOptions(
name='containernamespace',
options={'permissions': [('namespace_add_containerdistribution', 'Add any distribution to a namespace'), ('namespace_delete_containerdistribution', 'Delete any distribution from a namespace'), ('namespace_view_containerdistribution', 'View any distribution in a namespace'), ('namespace_pull_containerdistribution', 'Pull from any distribution in a namespace'), ('namespace_push_containerdistribution', 'Push to any distribution in a namespace'), ('namespace_change_containerdistribution', 'Change any distribution in a namespace'), ('namespace_view_containerpushrepository', 'View any push repository in a namespace'), ('namespace_modify_content_containerpushrepository', 'Modify content in any push repository in a namespace'), ('namespace_change_containerpushrepository', 'Update any existing push repository in a namespace'), ('manage_roles_containernamespace', 'Can manage role assignments on container namespace')]},
),
]
8 changes: 8 additions & 0 deletions pulp_container/app/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,10 @@ class Meta:
"namespace_change_containerpushrepository",
"Update any existing push repository in a namespace",
),
(
"manage_roles_containernamespace",
"Can manage role assignments on container namespace",
),
]


Expand Down Expand Up @@ -561,6 +565,10 @@ class Meta:
permissions = [
("pull_containerdistribution", "Can pull from a registry repo"),
("push_containerdistribution", "Can push into the registry repo"),
(
"manage_roles_containerdistribution",
"Can manage role assignments on container distribution",
),
]


Expand Down
6 changes: 2 additions & 4 deletions pulp_container/app/registry_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,10 @@

from django.conf import settings

from guardian.shortcuts import get_objects_for_user

from pulpcore.plugin.models import Artifact, ContentArtifact, Task, UploadChunk
from pulpcore.plugin.files import PulpTemporaryUploadedFile
from pulpcore.plugin.tasking import add_and_remove, dispatch
from pulpcore.plugin.util import get_objects_for_user
from rest_framework.exceptions import (
AuthenticationFailed,
NotAuthenticated,
Expand Down Expand Up @@ -527,8 +526,7 @@ def get_queryset(self, *args, **kwargs):
self.request.user, distribution_permission, queryset
)

namespace_refs = queryset.values_list("namespace", flat=True)
namespaces = models.ContainerNamespace.objects.filter(pk__in=namespace_refs)
namespaces = models.ContainerNamespace.objects.all()
repositories_by_namespace = get_objects_for_user(
self.request.user, namespace_permission, namespaces
)
Expand Down
Loading

0 comments on commit a2e1edb

Please sign in to comment.