Add basic CRUD for federation mapping
Change-Id: Ie3991efda6d2437821f67e3c87e111886578e830 Partially-Implements: blueprint keystone-federation-mapping
This commit is contained in:
parent
78bfa9727d
commit
fbf10e9dad
@ -795,3 +795,31 @@ def identity_provider_delete(request, idp_id):
|
||||
def identity_provider_list(request):
|
||||
manager = keystoneclient(request, admin=True).federation.identity_providers
|
||||
return manager.list()
|
||||
|
||||
|
||||
def mapping_create(request, mapping_id, rules):
|
||||
manager = keystoneclient(request, admin=True).federation.mappings
|
||||
try:
|
||||
return manager.create(mapping_id=mapping_id, rules=rules)
|
||||
except keystone_exceptions.Conflict:
|
||||
raise exceptions.Conflict()
|
||||
|
||||
|
||||
def mapping_get(request, mapping_id):
|
||||
manager = keystoneclient(request, admin=True).federation.mappings
|
||||
return manager.get(mapping_id)
|
||||
|
||||
|
||||
def mapping_update(request, mapping_id, rules):
|
||||
manager = keystoneclient(request, admin=True).federation.mappings
|
||||
return manager.update(mapping_id, rules=rules)
|
||||
|
||||
|
||||
def mapping_delete(request, mapping_id):
|
||||
manager = keystoneclient(request, admin=True).federation.mappings
|
||||
return manager.delete(mapping_id)
|
||||
|
||||
|
||||
def mapping_list(request):
|
||||
manager = keystoneclient(request, admin=True).federation.mappings
|
||||
return manager.list()
|
||||
|
86
openstack_dashboard/dashboards/identity/mappings/forms.py
Normal file
86
openstack_dashboard/dashboards/identity/mappings/forms.py
Normal file
@ -0,0 +1,86 @@
|
||||
# Copyright (C) 2015 Yahoo! Inc. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import json
|
||||
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from horizon import exceptions
|
||||
from horizon import forms
|
||||
from horizon import messages
|
||||
|
||||
from openstack_dashboard import api
|
||||
|
||||
|
||||
class CreateMappingForm(forms.SelfHandlingForm):
|
||||
id = forms.CharField(label=_("Mapping ID"),
|
||||
max_length=64,
|
||||
help_text=_("User-defined unique id to identify "
|
||||
"the mapping."))
|
||||
rules = forms.CharField(label=_("Rules"),
|
||||
widget=forms.widgets.Textarea(attrs={'rows': 4}),
|
||||
help_text=_("Set of rules to map federation "
|
||||
"protocol attributes to Identity "
|
||||
"API objects."))
|
||||
|
||||
def handle(self, request, data):
|
||||
try:
|
||||
rules = json.loads(data["rules"])
|
||||
new_mapping = api.keystone.mapping_create(
|
||||
request,
|
||||
data["id"],
|
||||
rules=rules)
|
||||
messages.success(request,
|
||||
_("Mapping created successfully."))
|
||||
return new_mapping
|
||||
except exceptions.Conflict:
|
||||
msg = _('Mapping ID "%s" is already used.') % data["id"]
|
||||
messages.error(request, msg)
|
||||
except (TypeError, ValueError):
|
||||
msg = _("Unable to create mapping. Rules has malformed JSON data.")
|
||||
messages.error(request, msg)
|
||||
except Exception:
|
||||
exceptions.handle(request,
|
||||
_("Unable to create mapping."))
|
||||
return False
|
||||
|
||||
|
||||
class UpdateMappingForm(forms.SelfHandlingForm):
|
||||
id = forms.CharField(label=_("Mapping ID"),
|
||||
widget=forms.TextInput(
|
||||
attrs={'readonly': 'readonly'}),
|
||||
help_text=_("User-defined unique id to "
|
||||
"identify the mapping."))
|
||||
rules = forms.CharField(label=_("Rules"),
|
||||
widget=forms.widgets.Textarea(attrs={'rows': 4}),
|
||||
help_text=_("Set of rules to map federation "
|
||||
"protocol attributes to Identity "
|
||||
"API objects."))
|
||||
|
||||
def handle(self, request, data):
|
||||
try:
|
||||
rules = json.loads(data["rules"])
|
||||
api.keystone.mapping_update(
|
||||
request,
|
||||
data['id'],
|
||||
rules=rules)
|
||||
messages.success(request,
|
||||
_("Mapping updated successfully."))
|
||||
return True
|
||||
except (TypeError, ValueError):
|
||||
msg = _("Unable to update mapping. Rules has malformed JSON data.")
|
||||
messages.error(request, msg)
|
||||
except Exception:
|
||||
exceptions.handle(request,
|
||||
_('Unable to update mapping.'))
|
30
openstack_dashboard/dashboards/identity/mappings/panel.py
Normal file
30
openstack_dashboard/dashboards/identity/mappings/panel.py
Normal file
@ -0,0 +1,30 @@
|
||||
# Copyright (C) 2015 Yahoo! Inc. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
import horizon
|
||||
|
||||
from openstack_dashboard.api import keystone
|
||||
|
||||
|
||||
class Mappings(horizon.Panel):
|
||||
name = _("Mappings")
|
||||
slug = 'mappings'
|
||||
policy_rules = (("identity", "identity:list_mappings"),)
|
||||
|
||||
@staticmethod
|
||||
def can_register():
|
||||
return (keystone.VERSIONS.active >= 3 and
|
||||
keystone.is_federation_management_enabled())
|
91
openstack_dashboard/dashboards/identity/mappings/tables.py
Normal file
91
openstack_dashboard/dashboards/identity/mappings/tables.py
Normal file
@ -0,0 +1,91 @@
|
||||
# Copyright (C) 2015 Yahoo! Inc. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import json
|
||||
|
||||
from django.utils import safestring
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from django.utils.translation import ungettext_lazy
|
||||
|
||||
from horizon import tables
|
||||
|
||||
from openstack_dashboard import api
|
||||
|
||||
|
||||
class CreateMappingLink(tables.LinkAction):
|
||||
name = "create"
|
||||
verbose_name = _("Create Mapping")
|
||||
url = "horizon:identity:mappings:create"
|
||||
classes = ("ajax-modal",)
|
||||
icon = "plus"
|
||||
policy_rules = (("identity", "identity:create_mapping"),)
|
||||
|
||||
|
||||
class EditMappingLink(tables.LinkAction):
|
||||
name = "edit"
|
||||
verbose_name = _("Edit")
|
||||
url = "horizon:identity:mappings:update"
|
||||
classes = ("ajax-modal",)
|
||||
icon = "pencil"
|
||||
policy_rules = (("identity", "identity:update_mapping"),)
|
||||
|
||||
|
||||
class DeleteMappingsAction(tables.DeleteAction):
|
||||
@staticmethod
|
||||
def action_present(count):
|
||||
return ungettext_lazy(
|
||||
u"Delete Mapping",
|
||||
u"Delete Mappings",
|
||||
count
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def action_past(count):
|
||||
return ungettext_lazy(
|
||||
u"Deleted Mapping",
|
||||
u"Deleted Mappings",
|
||||
count
|
||||
)
|
||||
policy_rules = (("identity", "identity:delete_mapping"),)
|
||||
|
||||
def delete(self, request, obj_id):
|
||||
api.keystone.mapping_delete(request, obj_id)
|
||||
|
||||
|
||||
class MappingFilterAction(tables.FilterAction):
|
||||
def filter(self, table, mappings, filter_string):
|
||||
"""Naive case-insensitive search."""
|
||||
q = filter_string.lower()
|
||||
return [mapping for mapping in mappings
|
||||
if q in mapping.ud.lower()]
|
||||
|
||||
|
||||
def get_rules_as_json(mapping):
|
||||
rules = getattr(mapping, 'rules', None)
|
||||
if rules:
|
||||
rules = json.dumps(rules, indent=4)
|
||||
return safestring.mark_safe(rules)
|
||||
|
||||
|
||||
class MappingsTable(tables.DataTable):
|
||||
id = tables.Column('id', verbose_name=_('Mapping ID'))
|
||||
description = tables.Column(get_rules_as_json,
|
||||
verbose_name=_('Rules'))
|
||||
|
||||
class Meta(object):
|
||||
name = "idp_mappings"
|
||||
verbose_name = _("Attribute Mappings")
|
||||
row_actions = (EditMappingLink, DeleteMappingsAction)
|
||||
table_actions = (MappingFilterAction, CreateMappingLink,
|
||||
DeleteMappingsAction)
|
@ -0,0 +1,9 @@
|
||||
{% extends "horizon/common/_modal_form.html" %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block modal-body-right %}
|
||||
<h3>{% trans "Description:" %}</h3>
|
||||
<p>{% trans "Create a mapping." %}</p>
|
||||
<p>{% trans "A mapping is a set of rules to map federation protocol attributes to Identity API objects. An identity provider can have a single mapping specified per protocol. A mapping is simply a list of rules. The only Identity API objects that will support mapping are: user and group." %}</p>
|
||||
<p>{% trans "A rule contains a remote attribute description and the destination local attribute." %}</p>
|
||||
{% endblock %}
|
@ -0,0 +1,8 @@
|
||||
{% extends "horizon/common/_modal_form.html" %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block modal-body-right %}
|
||||
<h3>{% trans "Description:" %}</h3>
|
||||
<p>{% trans "Edit the mapping's details." %}</p>
|
||||
<p>{% trans "A rule contains a remote attribute description and the destination local attribute." %}</p>
|
||||
{% endblock %}
|
@ -0,0 +1,7 @@
|
||||
{% extends 'base.html' %}
|
||||
{% load i18n %}
|
||||
{% block title %}{% trans "Create Mapping" %}{% endblock %}
|
||||
|
||||
{% block main %}
|
||||
{% include 'identity/mappings/_create.html' %}
|
||||
{% endblock %}
|
@ -0,0 +1,7 @@
|
||||
{% extends 'base.html' %}
|
||||
{% load i18n %}
|
||||
{% block title %}{% trans "Mappings" %}{% endblock %}
|
||||
|
||||
{% block main %}
|
||||
{{ table.render }}
|
||||
{% endblock %}
|
@ -0,0 +1,7 @@
|
||||
{% extends 'base.html' %}
|
||||
{% load i18n %}
|
||||
{% block title %}{% trans "Update Mapping" %}{% endblock %}
|
||||
|
||||
{% block main %}
|
||||
{% include 'identity/mappings/_update.html' %}
|
||||
{% endblock %}
|
107
openstack_dashboard/dashboards/identity/mappings/tests.py
Normal file
107
openstack_dashboard/dashboards/identity/mappings/tests.py
Normal file
@ -0,0 +1,107 @@
|
||||
# Copyright (C) 2015 Yahoo! Inc. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import json
|
||||
|
||||
from django.core.urlresolvers import reverse
|
||||
from django import http
|
||||
|
||||
from mox3.mox import IgnoreArg # noqa
|
||||
from mox3.mox import IsA # noqa
|
||||
|
||||
from openstack_dashboard import api
|
||||
from openstack_dashboard.test import helpers as test
|
||||
|
||||
|
||||
MAPPINGS_INDEX_URL = reverse('horizon:identity:mappings:index')
|
||||
MAPPINGS_CREATE_URL = reverse('horizon:identity:mappings:create')
|
||||
MAPPINGS_UPDATE_URL = reverse('horizon:identity:mappings:update',
|
||||
args=['mapping_1'])
|
||||
|
||||
|
||||
class MappingsViewTests(test.BaseAdminViewTests):
|
||||
@test.create_stubs({api.keystone: ('mapping_list',)})
|
||||
def test_index(self):
|
||||
api.keystone.mapping_list(IgnoreArg()). \
|
||||
AndReturn(self.idp_mappings.list())
|
||||
|
||||
self.mox.ReplayAll()
|
||||
|
||||
res = self.client.get(MAPPINGS_INDEX_URL)
|
||||
|
||||
self.assertTemplateUsed(res, 'identity/mappings/index.html')
|
||||
self.assertItemsEqual(res.context['table'].data,
|
||||
self.idp_mappings.list())
|
||||
|
||||
@test.create_stubs({api.keystone: ('mapping_create', )})
|
||||
def test_create(self):
|
||||
mapping = self.idp_mappings.first()
|
||||
|
||||
api.keystone.mapping_create(IgnoreArg(),
|
||||
mapping.id,
|
||||
rules=mapping.rules). \
|
||||
AndReturn(mapping)
|
||||
|
||||
self.mox.ReplayAll()
|
||||
|
||||
formData = {'method': 'CreateMappingForm',
|
||||
'id': mapping.id,
|
||||
'rules': json.dumps(mapping.rules)}
|
||||
res = self.client.post(MAPPINGS_CREATE_URL, formData)
|
||||
|
||||
self.assertNoFormErrors(res)
|
||||
self.assertMessageCount(success=1)
|
||||
|
||||
@test.create_stubs({api.keystone: ('mapping_get',
|
||||
'mapping_update')})
|
||||
def test_update(self):
|
||||
mapping = self.idp_mappings.first()
|
||||
new_rules = [{"local": [], "remote": []}]
|
||||
|
||||
api.keystone.mapping_get(IsA(http.HttpRequest),
|
||||
mapping.id). \
|
||||
AndReturn(mapping)
|
||||
api.keystone.mapping_update(IsA(http.HttpRequest),
|
||||
mapping.id,
|
||||
rules=new_rules). \
|
||||
AndReturn(None)
|
||||
|
||||
self.mox.ReplayAll()
|
||||
|
||||
formData = {'method': 'UpdateMappingForm',
|
||||
'id': mapping.id,
|
||||
'rules': json.dumps(new_rules)}
|
||||
|
||||
res = self.client.post(MAPPINGS_UPDATE_URL, formData)
|
||||
|
||||
self.assertNoFormErrors(res)
|
||||
self.assertMessageCount(success=1)
|
||||
|
||||
@test.create_stubs({api.keystone: ('mapping_list',
|
||||
'mapping_delete')})
|
||||
def test_delete(self):
|
||||
mapping = self.idp_mappings.first()
|
||||
|
||||
api.keystone.mapping_list(IsA(http.HttpRequest)) \
|
||||
.AndReturn(self.idp_mappings.list())
|
||||
api.keystone.mapping_delete(IsA(http.HttpRequest),
|
||||
mapping.id) \
|
||||
.AndReturn(None)
|
||||
|
||||
self.mox.ReplayAll()
|
||||
|
||||
formData = {'action': 'idp_mappings__delete__%s' % mapping.id}
|
||||
res = self.client.post(MAPPINGS_INDEX_URL, formData)
|
||||
|
||||
self.assertNoFormErrors(res)
|
25
openstack_dashboard/dashboards/identity/mappings/urls.py
Normal file
25
openstack_dashboard/dashboards/identity/mappings/urls.py
Normal file
@ -0,0 +1,25 @@
|
||||
# Copyright (C) 2015 Yahoo! Inc. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from django.conf.urls import patterns
|
||||
from django.conf.urls import url
|
||||
|
||||
from openstack_dashboard.dashboards.identity.mappings import views
|
||||
|
||||
urlpatterns = patterns(
|
||||
'openstack_dashboard.dashboards.identity.mappings.views',
|
||||
url(r'^$', views.IndexView.as_view(), name='index'),
|
||||
url(r'^(?P<mapping_id>[^/]+)/update/$',
|
||||
views.UpdateView.as_view(), name='update'),
|
||||
url(r'^create/$', views.CreateView.as_view(), name='create'))
|
101
openstack_dashboard/dashboards/identity/mappings/views.py
Normal file
101
openstack_dashboard/dashboards/identity/mappings/views.py
Normal file
@ -0,0 +1,101 @@
|
||||
# Copyright (C) 2015 Yahoo! Inc. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import json
|
||||
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.core.urlresolvers import reverse_lazy
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from horizon import exceptions
|
||||
from horizon import forms
|
||||
from horizon import messages
|
||||
from horizon import tables
|
||||
from horizon.utils import memoized
|
||||
|
||||
from openstack_dashboard import api
|
||||
from openstack_dashboard import policy
|
||||
|
||||
from openstack_dashboard.dashboards.identity.mappings \
|
||||
import forms as mapping_forms
|
||||
from openstack_dashboard.dashboards.identity.mappings \
|
||||
import tables as mapping_tables
|
||||
|
||||
|
||||
class IndexView(tables.DataTableView):
|
||||
table_class = mapping_tables.MappingsTable
|
||||
template_name = 'identity/mappings/index.html'
|
||||
page_title = _("Mappings")
|
||||
|
||||
def get_data(self):
|
||||
mappings = []
|
||||
if policy.check((("identity", "identity:list_mappings"),),
|
||||
self.request):
|
||||
try:
|
||||
mappings = api.keystone.mapping_list(self.request)
|
||||
except Exception:
|
||||
exceptions.handle(
|
||||
self.request,
|
||||
_('Unable to retrieve mapping list.'))
|
||||
else:
|
||||
msg = _("Insufficient privilege level to view mapping "
|
||||
"information.")
|
||||
messages.info(self.request, msg)
|
||||
return mappings
|
||||
|
||||
|
||||
class UpdateView(forms.ModalFormView):
|
||||
template_name = 'identity/mappings/update.html'
|
||||
modal_header = _("Update Mapping")
|
||||
form_id = "update_mapping_form"
|
||||
form_class = mapping_forms.UpdateMappingForm
|
||||
submit_label = _("Update Mapping")
|
||||
submit_url = "horizon:identity:mappings:update"
|
||||
success_url = reverse_lazy('horizon:identity:mappings:index')
|
||||
page_title = _("Update Mapping")
|
||||
|
||||
@memoized.memoized_method
|
||||
def get_object(self):
|
||||
try:
|
||||
return api.keystone.mapping_get(
|
||||
self.request,
|
||||
self.kwargs['mapping_id'])
|
||||
except Exception:
|
||||
redirect = reverse("horizon:identity:mappings:index")
|
||||
exceptions.handle(self.request,
|
||||
_('Unable to update mapping.'),
|
||||
redirect=redirect)
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super(UpdateView, self).get_context_data(**kwargs)
|
||||
args = (self.get_object().id,)
|
||||
context['submit_url'] = reverse(self.submit_url, args=args)
|
||||
return context
|
||||
|
||||
def get_initial(self):
|
||||
mapping = self.get_object()
|
||||
rules = json.dumps(mapping.rules, indent=4)
|
||||
return {'id': mapping.id,
|
||||
'rules': rules}
|
||||
|
||||
|
||||
class CreateView(forms.ModalFormView):
|
||||
template_name = 'identity/mappings/create.html'
|
||||
modal_header = _("Create Mapping")
|
||||
form_id = "create_mapping_form"
|
||||
form_class = mapping_forms.CreateMappingForm
|
||||
submit_label = _("Create Mapping")
|
||||
submit_url = reverse_lazy("horizon:identity:mappings:create")
|
||||
success_url = reverse_lazy('horizon:identity:mappings:index')
|
||||
page_title = _("Create Mapping")
|
10
openstack_dashboard/enabled/_3080_identity_mappings_panel.py
Normal file
10
openstack_dashboard/enabled/_3080_identity_mappings_panel.py
Normal file
@ -0,0 +1,10 @@
|
||||
# The slug of the panel to be added to HORIZON_CONFIG. Required.
|
||||
PANEL = 'mappings'
|
||||
# The slug of the dashboard the PANEL associated with. Required.
|
||||
PANEL_DASHBOARD = 'identity'
|
||||
# The slug of the panel group the PANEL is associated with.
|
||||
PANEL_GROUP = 'federation'
|
||||
|
||||
# Python panel class of the PANEL to be added.
|
||||
ADD_PANEL = ('openstack_dashboard.dashboards.identity.'
|
||||
'mappings.panel.Mappings')
|
@ -24,6 +24,7 @@ from keystoneclient.v2_0 import roles
|
||||
from keystoneclient.v2_0 import tenants
|
||||
from keystoneclient.v2_0 import users
|
||||
from keystoneclient.v3.contrib.federation import identity_providers
|
||||
from keystoneclient.v3.contrib.federation import mappings
|
||||
from keystoneclient.v3 import domains
|
||||
from keystoneclient.v3 import groups
|
||||
from keystoneclient.v3 import role_assignments
|
||||
@ -146,6 +147,7 @@ def data(TEST):
|
||||
TEST.ec2 = utils.TestDataContainer()
|
||||
|
||||
TEST.identity_providers = utils.TestDataContainer()
|
||||
TEST.idp_mappings = utils.TestDataContainer()
|
||||
|
||||
admin_role_dict = {'id': '1',
|
||||
'name': 'admin'}
|
||||
@ -387,3 +389,39 @@ def data(TEST):
|
||||
identity_providers.IdentityProviderManager,
|
||||
idp_dict_2)
|
||||
TEST.identity_providers.add(idp_1, idp_2)
|
||||
|
||||
idp_mapping_dict = {
|
||||
"id": "mapping_1",
|
||||
"rules": [
|
||||
{
|
||||
"local": [
|
||||
{
|
||||
"user": {
|
||||
"name": "{0}"
|
||||
}
|
||||
},
|
||||
{
|
||||
"group": {
|
||||
"id": "0cd5e9"
|
||||
}
|
||||
}
|
||||
],
|
||||
"remote": [
|
||||
{
|
||||
"type": "UserName"
|
||||
},
|
||||
{
|
||||
"type": "orgPersonType",
|
||||
"not_any_of": [
|
||||
"Contractor",
|
||||
"Guest"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
idp_mapping = mappings.Mapping(
|
||||
mappings.MappingManager,
|
||||
idp_mapping_dict)
|
||||
TEST.idp_mappings.add(idp_mapping)
|
||||
|
@ -4,4 +4,6 @@ features:
|
||||
[`blueprint keystone-federation-idp <https://blueprints.launchpad.net/horizon/+spec/keystone-federation-idp>`_]
|
||||
Add support for managing keystone identity provider. To enable the panel,
|
||||
set ``OPENSTACK_KEYSTONE_FEDERATION_MANAGEMENT`` in the local_settting.py to True.
|
||||
|
||||
- >
|
||||
[`blueprint keystone-federation-mapping <https://blueprints.launchpad.net/horizon/+spec/keystone-federation-mapping>`_]
|
||||
Add basic support for managing keystone federation mapping.
|
||||
|
Loading…
x
Reference in New Issue
Block a user