Skip to content

Commit

Permalink
Merge pull request pulp#679 from gerrod3/rbac
Browse files Browse the repository at this point in the history
Add RBAC support
  • Loading branch information
gerrod3 authored Jun 25, 2024
2 parents 5f58544 + c030d2b commit fc5d0a4
Show file tree
Hide file tree
Showing 13 changed files with 925 additions and 51 deletions.
1 change: 1 addition & 0 deletions CHANGES/399.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Added RBAC support.
1 change: 1 addition & 0 deletions docs/tech-preview.rst
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@ The following features are currently being released as part of a tech preview
* ``Twine`` upload packages to indexes at endpoints '/simple` or '/legacy'.
* Create pull-through caches of remote sources.
* Pulp Domain support
* RBAC support
53 changes: 53 additions & 0 deletions pulp_python/app/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
from django.db.models.signals import post_migrate
from pulpcore.plugin import PulpPluginAppConfig
from gettext import gettext as _


class PulpPythonPluginAppConfig(PulpPluginAppConfig):
Expand All @@ -11,3 +13,54 @@ class PulpPythonPluginAppConfig(PulpPluginAppConfig):
version = "3.12.0.dev"
python_package_name = "pulp-python"
domain_compatible = True

def ready(self):
"""Register PyPI access policy hook."""
super().ready()
post_migrate.connect(
_populate_pypi_access_policies,
sender=self,
dispatch_uid="populate_pypi_access_policies_identifier",
)


# TODO: Remove this when https://github.com/pulp/pulpcore/issues/5500 is resolved
def _populate_pypi_access_policies(sender, apps, verbosity, **kwargs):
from pulp_python.app.pypi.views import PyPIView, SimpleView, UploadView, MetadataView

try:
AccessPolicy = apps.get_model("core", "AccessPolicy")
except LookupError:
if verbosity >= 1:
print(_("AccessPolicy model does not exist. Skipping initialization."))
return

for viewset in (PyPIView, SimpleView, UploadView, MetadataView):
access_policy = getattr(viewset, "DEFAULT_ACCESS_POLICY", None)
if access_policy is not None:
viewset_name = viewset.urlpattern()
db_access_policy, created = AccessPolicy.objects.get_or_create(
viewset_name=viewset_name, defaults=access_policy
)
if created:
if verbosity >= 1:
print(
"Access policy for {viewset_name} created.".format(
viewset_name=viewset_name
)
)
elif not db_access_policy.customized:
dirty = False
for key in ["statements", "creation_hooks", "queryset_scoping"]:
value = access_policy.get(key)
if getattr(db_access_policy, key, None) != value:
setattr(db_access_policy, key, value)
dirty = True
if dirty:
db_access_policy.save()
if verbosity >= 1:
print(
"Access policy for {viewset_name} updated.".format(
viewset_name=viewset_name
)
)
30 changes: 30 additions & 0 deletions pulp_python/app/global_access_conditions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
from django.conf import settings


# Access Condition methods that can be used with PyPI access policies


def index_has_perm(request, view, action, perm="python.view_pythondistribution"):
"""Access Policy condition that checks if the user has the perm on the index(distro)."""
if request.user.has_perm(perm):
return True
if settings.DOMAIN_ENABLED:
if request.user.has_perm(perm, obj=request.pulp_domain):
return True
return request.user.has_perm(perm, obj=view.distribution)


def index_has_repo_perm(request, view, action, perm="python.view_pythonrepository"):
"""
Access Policy condition that checks if the user has the perm on the index's repository.
If index doesn't have a repository, then default return True.
"""
if request.user.has_perm(perm):
return True
if settings.DOMAIN_ENABLED:
if request.user.has_perm(perm, obj=request.pulp_domain):
return True
if repo := view.distribution.repository:
return request.user.has_perm(perm, obj=repo.cast())
return True
29 changes: 29 additions & 0 deletions pulp_python/app/migrations/0013_add_rbac_permissions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Generated by Django 4.2.10 on 2024-06-14 01:25

from django.db import migrations


class Migration(migrations.Migration):

dependencies = [
('python', '0012_add_domain'),
]

operations = [
migrations.AlterModelOptions(
name='pythondistribution',
options={'default_related_name': '%(app_label)s_%(model_name)s', 'permissions': [('manage_roles_pythondistribution', 'Can manage roles on python distributions')]},
),
migrations.AlterModelOptions(
name='pythonpublication',
options={'default_related_name': '%(app_label)s_%(model_name)s', 'permissions': [('manage_roles_pythonpublication', 'Can manage roles on python publications')]},
),
migrations.AlterModelOptions(
name='pythonremote',
options={'default_related_name': '%(app_label)s_%(model_name)s', 'permissions': [('manage_roles_pythonremote', 'Can manage roles on python remotes')]},
),
migrations.AlterModelOptions(
name='pythonrepository',
options={'default_related_name': '%(app_label)s_%(model_name)s', 'permissions': [('sync_pythonrepository', 'Can start a sync task'), ('modify_pythonrepository', 'Can modify content of the repository'), ('manage_roles_pythonrepository', 'Can manage roles on python repositories'), ('repair_pythonrepository', 'Can repair repository versions')]},
),
]
24 changes: 20 additions & 4 deletions pulp_python/app/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from django.db import models
from django.conf import settings
from pulpcore.plugin.models import (
AutoAddObjPermsMixin,
Content,
Publication,
Distribution,
Expand Down Expand Up @@ -47,7 +48,7 @@
)


class PythonDistribution(Distribution):
class PythonDistribution(Distribution, AutoAddObjPermsMixin):
"""
Distribution for 'Python' Content.
"""
Expand Down Expand Up @@ -119,6 +120,9 @@ def content_handler(self, path):

class Meta:
default_related_name = "%(app_label)s_%(model_name)s"
permissions = [
("manage_roles_pythondistribution", "Can manage roles on python distributions"),
]


class NormalizeName(models.Transform):
Expand Down Expand Up @@ -213,7 +217,7 @@ class Meta:
unique_together = ("sha256", "_pulp_domain")


class PythonPublication(Publication):
class PythonPublication(Publication, AutoAddObjPermsMixin):
"""
A Publication for PythonContent.
"""
Expand All @@ -222,9 +226,12 @@ class PythonPublication(Publication):

class Meta:
default_related_name = "%(app_label)s_%(model_name)s"
permissions = [
("manage_roles_pythonpublication", "Can manage roles on python publications"),
]


class PythonRemote(Remote):
class PythonRemote(Remote, AutoAddObjPermsMixin):
"""
A Remote for Python Content.
Expand Down Expand Up @@ -259,9 +266,12 @@ def get_remote_artifact_content_type(self, relative_path=None):

class Meta:
default_related_name = "%(app_label)s_%(model_name)s"
permissions = [
("manage_roles_pythonremote", "Can manage roles on python remotes"),
]


class PythonRepository(Repository):
class PythonRepository(Repository, AutoAddObjPermsMixin):
"""
Repository for "python" content.
"""
Expand All @@ -274,6 +284,12 @@ class PythonRepository(Repository):

class Meta:
default_related_name = "%(app_label)s_%(model_name)s"
permissions = [
("sync_pythonrepository", "Can start a sync task"),
("modify_pythonrepository", "Can modify content of the repository"),
("manage_roles_pythonrepository", "Can manage roles on python repositories"),
("repair_pythonrepository", "Can repair repository versions"),
]

def on_new_version(self, version):
"""
Expand Down
4 changes: 2 additions & 2 deletions pulp_python/app/pypi/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,6 @@ class PackageUploadTaskSerializer(serializers.Serializer):
A Serializer for responding to a package upload task.
"""

session = serializers.CharField()
session = serializers.CharField(allow_null=True)
task = serializers.CharField()
task_start_time = serializers.DateTimeField()
task_start_time = serializers.DateTimeField(allow_null=True)
Loading

0 comments on commit fc5d0a4

Please sign in to comment.