Merge ~rodrigo-barbieri2010/ubuntu/+source/horizon:lp1827120_zed into ~ubuntu-openstack-dev/ubuntu/+source/horizon:stable/zed

Proposed by Rodrigo Barbieri
Status: Merged
Merged at revision: 5716c233c854f0e2e800050739cd1af39510ab31
Proposed branch: ~rodrigo-barbieri2010/ubuntu/+source/horizon:lp1827120_zed
Merge into: ~ubuntu-openstack-dev/ubuntu/+source/horizon:stable/zed
Diff against target: 152 lines (+130/-0)
3 files modified
debian/changelog (+7/-0)
debian/patches/lp1827120.patch (+122/-0)
debian/patches/series (+1/-0)
Reviewer Review Type Date Requested Status
Ubuntu OpenStack uploaders Pending
Review via email: mp+434094@code.launchpad.net
To post a comment you must log in.
Revision history for this message
Corey Bryant (corey.bryant) :
Revision history for this message
Corey Bryant (corey.bryant) :

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/debian/changelog b/debian/changelog
2index fd391bc..1ae2a0f 100644
3--- a/debian/changelog
4+++ b/debian/changelog
5@@ -1,3 +1,10 @@
6+horizon (4:23.0.0-0ubuntu2) kinetic; urgency=medium
7+
8+ * d/p/lp1827120.patch: Fix missing project_id in application credential
9+ create when user has both project+domain admin role (LP#1827120).
10+
11+ -- Rodrigo Barbieri <rodrigo.barbieri@canonical.com> Mon, 05 Dec 2022 13:27:43 +0000
12+
13 horizon (4:23.0.0-0ubuntu1.1) UNRELEASED; urgency=medium
14
15 * d/gbp.conf: Create stable/zed branch.
16diff --git a/debian/patches/lp1827120.patch b/debian/patches/lp1827120.patch
17new file mode 100644
18index 0000000..d288828
19--- /dev/null
20+++ b/debian/patches/lp1827120.patch
21@@ -0,0 +1,122 @@
22+From 778a52e66aeab883b31db729e04944eeecfec6a2 Mon Sep 17 00:00:00 2001
23+From: Rodrigo Barbieri <rodrigo.barbieri2010@gmail.com>
24+Date: Wed, 7 Sep 2022 10:52:48 -0300
25+Subject: [PATCH] Fix app cred create without project_id for domain admins
26+
27+Users with domain admin role that are not cloud admins are
28+not able to get scoped context and create an application
29+credential with project_id, so this change forces the
30+scoped context in that particular case.
31+
32+Closes-bug: #1827120
33+Change-Id: I076a97a6f943ab74a2db8bc5179a7db194009db4
34+(cherry picked from commit 6eeaf9852478e25ff77c21117664ac126c5357a4)
35+---
36+ openstack_dashboard/api/keystone.py | 17 +++++--
37+ .../test/unit/api/test_keystone.py | 44 +++++++++++++++++++
38+ 2 files changed, 58 insertions(+), 3 deletions(-)
39+
40+diff --git a/openstack_dashboard/api/keystone.py b/openstack_dashboard/api/keystone.py
41+index d8aca8e71..cfaebfeab 100644
42+--- a/openstack_dashboard/api/keystone.py
43++++ b/openstack_dashboard/api/keystone.py
44+@@ -120,7 +120,7 @@ def _get_endpoint_url(request, endpoint_type, catalog=None):
45+ return url
46+
47+
48+-def keystoneclient(request, admin=False):
49++def keystoneclient(request, admin=False, force_scoped=False):
50+ """Returns a client connected to the Keystone backend.
51+
52+ Several forms of authentication are supported:
53+@@ -152,7 +152,8 @@ def keystoneclient(request, admin=False):
54+
55+ # If user is Cloud Admin, Domain Admin or Mixed Domain Admin and there
56+ # is no domain context specified, use domain scoped token
57+- if is_domain_admin(request) and not is_domain_context_specified:
58++ if (is_domain_admin(request) and not is_domain_context_specified and
59++ not force_scoped):
60+ domain_token = request.session.get('domain_token')
61+ if domain_token:
62+ token_id = getattr(domain_token, 'auth_token', None)
63+@@ -995,7 +996,17 @@ def application_credential_create(request, name, secret=None,
64+ roles=None, unrestricted=False,
65+ access_rules=None):
66+ user = request.user.id
67+- manager = keystoneclient(request).application_credentials
68++ # NOTE(ganso): users with domain admin role that are not cloud admins are
69++ # not able to get scoped context and create an application credential with
70++ # project_id, so only in this particular case we force a scoped context
71++ force_scoped = False
72++ if (request.user.project_id and request.session.get("domain_token") and
73++ not policy.check(
74++ (("identity", "identity:update_domain"),), request)):
75++ force_scoped = True
76++
77++ manager = keystoneclient(
78++ request, force_scoped=force_scoped).application_credentials
79+ try:
80+ return manager.create(name=name, user=user, secret=secret,
81+ description=description, expires_at=expires_at,
82+diff --git a/openstack_dashboard/test/unit/api/test_keystone.py b/openstack_dashboard/test/unit/api/test_keystone.py
83+index 4598c2d50..71e8a6314 100644
84+--- a/openstack_dashboard/test/unit/api/test_keystone.py
85++++ b/openstack_dashboard/test/unit/api/test_keystone.py
86+@@ -21,6 +21,7 @@ from unittest import mock
87+
88+ from django.test.utils import override_settings
89+ from openstack_dashboard import api
90++from openstack_dashboard import policy
91+ from openstack_dashboard.test import helpers as test
92+
93+
94+@@ -164,3 +165,46 @@ class APIVersionTests(test.APIMockTestCase):
95+ keystoneclient.session.get_endpoint_data.assert_called_once_with(
96+ service_type='identity')
97+ self.assertEqual((3, 10), api_version)
98++
99++
100++class ApplicationCredentialsAPITests(test.APIMockTestCase):
101++
102++ @mock.patch.object(policy, 'check')
103++ @mock.patch.object(api.keystone, 'keystoneclient')
104++ def test_application_credential_create_domain_token_removed(
105++ self, mock_keystoneclient, mock_policy):
106++ self.request.session['domain_token'] = 'some_token'
107++ mock_policy.return_value = False
108++ api.keystone.application_credential_create(self.request, None)
109++ mock_keystoneclient.assert_called_once_with(
110++ self.request, force_scoped=True)
111++
112++ @mock.patch.object(policy, 'check')
113++ @mock.patch.object(api.keystone, 'keystoneclient')
114++ def test_application_credential_create_domain_token_not_removed_policy_true(
115++ self, mock_keystoneclient, mock_policy):
116++ self.request.session['domain_token'] = 'some_token'
117++ mock_policy.return_value = True
118++ api.keystone.application_credential_create(self.request, None)
119++ mock_keystoneclient.assert_called_once_with(
120++ self.request, force_scoped=False)
121++
122++ @mock.patch.object(policy, 'check')
123++ @mock.patch.object(api.keystone, 'keystoneclient')
124++ def test_application_credential_create_domain_token_not_removed_no_token(
125++ self, mock_keystoneclient, mock_policy):
126++ mock_policy.return_value = True
127++ api.keystone.application_credential_create(self.request, None)
128++ mock_keystoneclient.assert_called_once_with(
129++ self.request, force_scoped=False)
130++
131++ @mock.patch.object(policy, 'check')
132++ @mock.patch.object(api.keystone, 'keystoneclient')
133++ def test_application_credential_create_domain_token_not_removed_no_project(
134++ self, mock_keystoneclient, mock_policy):
135++ self.request.session['domain_token'] = 'some_token'
136++ mock_policy.return_value = True
137++ self.request.user.project_id = None
138++ api.keystone.application_credential_create(self.request, None)
139++ mock_keystoneclient.assert_called_once_with(
140++ self.request, force_scoped=False)
141+--
142+2.34.1
143+
144diff --git a/debian/patches/series b/debian/patches/series
145index aa1c9f6..632dbee 100644
146--- a/debian/patches/series
147+++ b/debian/patches/series
148@@ -3,3 +3,4 @@ fix-dashboard-manage.patch
149 ubuntu_settings.patch
150 embedded-xstatic.patch
151 django-4-fix-csrf-reasons-list.patch
152+lp1827120.patch

Subscribers

People subscribed via source and target branches