diff --git a/rbac/internal/integration_views.py b/rbac/internal/integration_views.py
new file mode 100644
index 000000000..0381963ea
--- /dev/null
+++ b/rbac/internal/integration_views.py
@@ -0,0 +1,61 @@
+#
+# Copyright 2020 Red Hat, Inc.
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see .
+#
+
+"""View for OCM group/role API."""
+from audioop import reverse
+import datetime
+import json
+import logging
+
+import pytz
+from django.conf import settings
+from django.db import transaction
+from django.db.migrations.recorder import MigrationRecorder
+from django.http import Http404, HttpResponse
+from django.shortcuts import redirect, reverse
+from management import views
+from management.cache import TenantCache
+from management.models import Group, Role
+
+
+from api.models import Tenant
+
+
+logger = logging.getLogger(__name__)
+TENANTS = TenantCache()
+
+def groups(request, account_number):
+ username = request.GET.get("username")
+ if username:
+ base_url = reverse("group-list")
+ url = f'{base_url}?principals={username}'
+ return redirect(url)
+ else:
+ return Http404
+
+def groups_for_principal(request, account_number, username):
+ base_url = reverse("group-list")
+ url = f'{base_url}?principals={username}'
+ return redirect(url)
+
+def roles_from_group(request, account_number, uuid):
+ return redirect("group-roles", uuid=uuid)
+
+def roles_for_group(request, account_number, username, uuid):
+ base_url = reverse("group-roles", kwargs={'uuid': uuid})
+ url = f'{base_url}?principals={username}'
+ return redirect(url)
\ No newline at end of file
diff --git a/rbac/internal/middleware.py b/rbac/internal/middleware.py
index 29e77ec02..663f1def3 100644
--- a/rbac/internal/middleware.py
+++ b/rbac/internal/middleware.py
@@ -22,11 +22,14 @@
from django.conf import settings
from django.http import HttpResponseForbidden
+from django.shortcuts import get_object_or_404
+from django.urls import resolve
from django.utils.deprecation import MiddlewareMixin
from api.common import RH_IDENTITY_HEADER
-from api.models import User
+from api.models import User, Tenant
from api.serializers import extract_header
+from rbac.middleware import IdentityHeaderMiddleware
logger = logging.getLogger(__name__)
@@ -58,8 +61,14 @@ def process_request(self, request):
logger.error("Malformed X-RH-Identity header.")
return HttpResponseForbidden()
+ if "integration" in resolve(request.path).url_name:
+ return IdentityHeaderMiddleware.process_request(self, request)
+
request.user = user
def process_response(self, request, response):
"""Process responses for internal identity middleware."""
return response
+
+ def get_tenant(self, request):
+ request.tenant = get_object_or_404(Tenant, tenant_name=self.tenant_re.match(request.path_info).group('tenant_id'))
\ No newline at end of file
diff --git a/rbac/internal/urls.py b/rbac/internal/urls.py
index 496b89cf5..4a9006bbd 100644
--- a/rbac/internal/urls.py
+++ b/rbac/internal/urls.py
@@ -19,13 +19,17 @@
from django.urls import path
-from . import views
+from . import integration_views, views
from .views import trigger_error
urlpatterns = [
path("api/tenant/unmodified/", views.list_unmodified_tenants),
path("api/tenant/", views.list_tenants),
path("api/tenant//", views.tenant_view),
+ path("api/tenant//groups/", integration_views.groups, name="integration-groups"),
+ path("api/tenant//groups//roles/", integration_views.roles_from_group, name="integration-group-roles"),
+ path("api/tenant//principal//groups/", integration_views.groups_for_principal, name="integration-princ-groups"),
+ path("api/tenant//principal//groups//roles/", integration_views.roles_for_group, name="integration-princ-roles"),
path("api/migrations/run/", views.run_migrations),
path("api/migrations/progress/", views.migration_progress),
path("api/seeds/run/", views.run_seeds),
diff --git a/rbac/management/group/view.py b/rbac/management/group/view.py
index d2de3e876..d18b47c61 100644
--- a/rbac/management/group/view.py
+++ b/rbac/management/group/view.py
@@ -96,16 +96,31 @@ def roles_filter(self, queryset, field, values):
queryset = queryset.filter(policies__roles__name__icontains=role_name)
return queryset
+ def principal_filter(self, queryset, field, values):
+ """Filter for groups containing principals."""
+ if not values:
+ key = "groups_filter"
+ message = "No principals provided to filter groups!"
+ error = {key: [_(message)]}
+ raise serializers.ValidationError(error)
+ principals = [value.lower() for value in values.split(",")]
+
+ for principal in principals:
+ queryset = queryset.filter(principals__username__icontains=principal)
+
+ return queryset
+
name = filters.CharFilter(field_name="name", method="name_filter")
role_names = filters.CharFilter(field_name="role_names", method="roles_filter")
uuid = filters.CharFilter(field_name="uuid", method="uuid_filter")
+ principals = filters.CharFilter(field_name="principals", method="principal_filter")
system = filters.BooleanFilter(field_name="system")
platform_default = filters.BooleanFilter(field_name="platform_default")
admin_default = filters.BooleanFilter(field_name="admin_default")
class Meta:
model = Group
- fields = ["name", "role_names", "uuid"]
+ fields = ["name", "role_names", "uuid", "principals"]
class GroupViewSet(
diff --git a/rbac/rbac/dev_middleware.py b/rbac/rbac/dev_middleware.py
index 6c4e33692..80125d30d 100644
--- a/rbac/rbac/dev_middleware.py
+++ b/rbac/rbac/dev_middleware.py
@@ -41,8 +41,8 @@ def process_request(self, request): # pylint: disable=no-self-use
"identity": {
"account_number": "10001",
"org_id": "11111",
- "type": "User",
- "user": {
+ "type": "Associate",
+ "associate": {
"username": "user_dev",
"email": "user_dev@foo.com",
"is_org_admin": True,
diff --git a/rbac/rbac/middleware.py b/rbac/rbac/middleware.py
index 65fa04f9a..d9c58d38a 100644
--- a/rbac/rbac/middleware.py
+++ b/rbac/rbac/middleware.py
@@ -74,7 +74,7 @@ class IdentityHeaderMiddleware(MiddlewareMixin):
header = RH_IDENTITY_HEADER
- def get_tenant(self, model, hostname, request):
+ def get_tenant(self, request):
"""Override the tenant selection logic."""
if settings.AUTHENTICATE_WITH_ORG_ID:
tenant_name = create_tenant_name(request.user.account)
@@ -184,7 +184,11 @@ def process_request(self, request): # pylint: disable=R1710
_, json_rh_auth = extract_header(request, self.header)
user.account = json_rh_auth.get("identity", {})["account_number"]
user.org_id = json_rh_auth.get("identity", {}).get("org_id")
- user_info = json_rh_auth.get("identity", {}).get("user", {})
+ usertype = json_rh_auth.get("identity", {}).get("type")
+ if usertype.lower() == "associate":
+ user_info = json_rh_auth.get("identity", {}).get("associate", {})
+ else:
+ user_info = json_rh_auth.get("identity", {}).get("user", {})
user.username = user_info["username"]
user.admin = user_info.get("is_org_admin")
user.internal = user_info.get("is_internal")
@@ -239,7 +243,7 @@ def process_request(self, request): # pylint: disable=R1710
raise error
if user.username and (user.account or user.org_id):
request.user = user
- request.tenant = self.get_tenant(model=None, hostname=None, request=request)
+ request.tenant = self.get_tenant(request=request)
def process_response(self, request, response): # pylint: disable=no-self-use
"""Process response for identity middleware.