Skip to content

Commit

Permalink
Merge branch 'ansible:master' into master
Browse files Browse the repository at this point in the history
  • Loading branch information
Dule-martins authored Oct 18, 2023
2 parents 740cd7b + 133f4c8 commit 4291b0c
Show file tree
Hide file tree
Showing 22 changed files with 372 additions and 100 deletions.
1 change: 1 addition & 0 deletions CHANGES/2775.misc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
set proper CONTENT_ORIGIN for ephemeral pr checks
1 change: 1 addition & 0 deletions CHANGES/2781.bugfix
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Allow all authenticated users to list and retrieve other users when using github social auth.
9 changes: 7 additions & 2 deletions dev/ephemeral/patch_ephemeral.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,14 @@ FE_ROUTE=$(oc get routes | awk '{print $1}' | grep front-end-aggregator)
if [ -n "${FE_ROUTE}" ]; then
CONTENT_ORIGIN=$(oc get route front-end-aggregator -o jsonpath='https://{.spec.host}{"\n"}')
else
CONTENT_ORIGIN=$(bonfire namespace describe ${NAMESPACE} | grep "Frontend route" | awk '{print $3}')
CONTENT_ORIGIN=$(bonfire namespace describe ${NAMESPACE} | grep "Gateway route" | awk '{print $3}')
fi
if [ -z "${CONTENT_ORIGIN}" ]; then
echo "ERROR: unable to determine CONTENT_ORIGIN"
exit 1
else
echo "CONTENT_ORIGIN = ${CONTENT_ORIGIN}"
fi
echo "CONTENT_ORIGIN = ${CONTENT_ORIGIN}"
oc patch clowdapp automation-hub --type=json \
-p '[{"op": "replace",
"path": "/spec/deployments/1/podSpec/env/1/value",
Expand Down
4 changes: 2 additions & 2 deletions dev/oci_env_integration/oci_env_configs/community.compose.env
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ DJANGO_SUPERUSER_USERNAME=admin
DJANGO_SUPERUSER_PASSWORD=admin

## Enable github social auth by setting these two values
SOCIAL_AUTH_GITHUB_KEY='abcd1234'
SOCIAL_AUTH_GITHUB_SECRET='abcd1234'
#SOCIAL_AUTH_GITHUB_KEY='abcd1234'
#SOCIAL_AUTH_GITHUB_SECRET='abcd1234'

PULP_GALAXY_API_PATH_PREFIX=/api/

Expand Down
17 changes: 17 additions & 0 deletions galaxy_ng/app/access_control/access_policy.py
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,23 @@ def v3_can_destroy_collections(self, request, view, action):
return True
return False

def v3_can_view_users(self, request, view, action):
"""
Community galaxy users need to be able to see one-another,
so that they can grant eachother access to their namespaces.
"""
SOCIAL_AUTH_GITHUB_KEY = settings.get("SOCIAL_AUTH_GITHUB_KEY", default=None)
SOCIAL_AUTH_GITHUB_SECRET = settings.get("SOCIAL_AUTH_GITHUB_SECRET", default=None)
is_github_social_auth = all([SOCIAL_AUTH_GITHUB_KEY, SOCIAL_AUTH_GITHUB_SECRET])

if is_github_social_auth:
return True

if request.user.has_perm('galaxy.view_user'):
return True

return False

def has_ansible_repo_perms(self, request, view, action, permission):
"""
Check if the user has model or object-level permissions
Expand Down
46 changes: 46 additions & 0 deletions galaxy_ng/app/access_control/fields.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from django.utils.translation import gettext_lazy as _
from django.contrib.auth import get_user_model

from rest_framework import serializers
from rest_framework.exceptions import ValidationError
Expand All @@ -10,6 +11,9 @@
from galaxy_ng.app.models import auth as auth_models


User = get_user_model()


class GroupPermissionField(serializers.Field):
def _validate_group(self, group_data):
if 'object_roles' not in group_data:
Expand Down Expand Up @@ -74,6 +78,48 @@ def to_internal_value(self, data):
return internal


class UserPermissionField(serializers.Field):

def _validate_user(self, user_data):
# FIXME - fill this in ...
pass

def to_representation(self, value):
rep = []
for user in value:
rep.append({
'id': user.id,
'name': user.username,
'object_roles': value[user]
})
return rep

def to_internal_value(self, data):
if not isinstance(data, list):
raise ValidationError(detail={
'users': _('Users must be a list of user objects')
})

internal = {}
for user_data in data:
self._validate_user(user_data)
user_filter = {}
for field in user_data:
if field in ('id', 'username'):
user_filter[field] = user_data[field]

user = User.objects.filter(**user_filter).first()
if not user:
raise ValidationError(detail={'user': _('Invalid user username or ID')})

if 'object_permissions' in user_data:
internal[user] = user_data['object_permissions']
if 'object_roles' in user_data:
internal[user] = user_data['object_roles']

return internal


class MyPermissionsField(serializers.Serializer):
def to_representation(self, original_obj):
request = self.context.get('request', None)
Expand Down
51 changes: 51 additions & 0 deletions galaxy_ng/app/access_control/mixins.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
assign_role,
remove_role,
get_groups_with_perms_attached_roles,
get_users_with_perms_attached_roles,
)

from django_lifecycle import hook
Expand Down Expand Up @@ -61,3 +62,53 @@ def _set_groups(self, groups):
def set_object_groups(self):
if self._groups:
self._set_groups(self._groups)


class UserModelPermissionsMixin:
_users = None

@property
def users(self):
return get_users_with_perms_attached_roles(
self, include_model_permissions=False, for_concrete_model=True)

@users.setter
def users(self, users):
self._set_users(users)

@transaction.atomic
def _set_users(self, users):
if self._state.adding:
self._users = users
else:
obj = self

# If the model is a proxy model, get the original model since pulp
# doesn't allow us to assign permissions to proxied models.
if self._meta.proxy:
obj = self._meta.concrete_model.objects.get(pk=self.pk)

current_users = get_users_with_perms_attached_roles(
obj, include_model_permissions=False)
for user in current_users:
for perm in current_users[user]:
remove_role(perm, user, obj)

for user in users:
for role in users[user]:
try:
assign_role(role, user, obj)
except BadRequest:
raise ValidationError(
detail={
'users': _(
'Role {role} does not exist or does not '
'have any permissions related to this object.'
).format(role=role)
}
)

@hook('after_save')
def set_object_users(self):
if self._users:
self._set_users(self._users)
4 changes: 2 additions & 2 deletions galaxy_ng/app/access_control/statements/standalone.py
Original file line number Diff line number Diff line change
Expand Up @@ -198,13 +198,13 @@
"action": ["list"],
"principal": "authenticated",
"effect": "allow",
"condition": "has_model_perms:galaxy.view_user"
"condition": ["v3_can_view_users"],
},
{
"action": ["retrieve"],
"principal": "authenticated",
"effect": "allow",
"condition": "has_model_perms:galaxy.view_user"
"condition": ["v3_can_view_users"],
},
{
"action": "destroy",
Expand Down
11 changes: 9 additions & 2 deletions galaxy_ng/app/api/v3/serializers/namespace.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,11 @@

from galaxy_ng.app import models
from galaxy_ng.app.tasks import dispatch_create_pulp_namespace_metadata
from galaxy_ng.app.access_control.fields import GroupPermissionField, MyPermissionsField
from galaxy_ng.app.access_control.fields import (
GroupPermissionField,
UserPermissionField,
MyPermissionsField
)
from galaxy_ng.app.api.base import RelatedFieldsBaseSerializer

log = logging.getLogger(__name__)
Expand Down Expand Up @@ -73,7 +77,8 @@ def validate_url(self, url):

class NamespaceSerializer(serializers.ModelSerializer):
links = NamespaceLinkSerializer(many=True, required=False)
groups = GroupPermissionField()
groups = GroupPermissionField(required=False)
users = UserPermissionField(required=False)
related_fields = NamespaceRelatedFieldSerializer(source="*")
avatar_url = fields.URLField(required=False, allow_blank=True)
avatar_sha256 = serializers.SerializerMethodField()
Expand All @@ -93,6 +98,7 @@ class Meta:
'description',
'links',
'groups',
'users',
'resources',
'related_fields',
'metadata_sha256',
Expand Down Expand Up @@ -178,6 +184,7 @@ class Meta:
'avatar_url',
'description',
'groups',
'users',
'related_fields',
'metadata_sha256',
'avatar_sha256'
Expand Down
6 changes: 5 additions & 1 deletion galaxy_ng/app/models/namespace.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,11 @@
__all__ = ("Namespace", "NamespaceLink")


class Namespace(LifecycleModel, mixins.GroupModelPermissionsMixin):
class Namespace(
LifecycleModel,
mixins.GroupModelPermissionsMixin,
mixins.UserModelPermissionsMixin
):
"""
A model representing Ansible content namespace.
Expand Down
11 changes: 11 additions & 0 deletions galaxy_ng/app/webserver_snippets/nginx.conf
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,14 @@ location /ui/ {
proxy_redirect off;
proxy_pass http://pulp-api/static/galaxy_ng/index.html;
}

location /api/ {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Host $http_host;
# we don't want nginx trying to do something clever with
# redirects, we set the Host: header above already.
proxy_redirect off;
proxy_pass http://pulp-api;
client_max_body_size 0;
}
Loading

0 comments on commit 4291b0c

Please sign in to comment.