1# Copyright 2012 United States Government as represented by the 2# Administrator of the National Aeronautics and Space Administration. 3# All Rights Reserved. 4# 5# Copyright 2012 OpenStack Foundation 6# Copyright 2012 Nebula, Inc. 7# 8# Licensed under the Apache License, Version 2.0 (the "License"); you may 9# not use this file except in compliance with the License. You may obtain 10# a copy of the License at 11# 12# http://www.apache.org/licenses/LICENSE-2.0 13# 14# Unless required by applicable law or agreed to in writing, software 15# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 16# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 17# License for the specific language governing permissions and limitations 18# under the License. 19 20import collections 21import logging 22from urllib import parse 23 24from django.conf import settings 25from django.utils.translation import ugettext_lazy as _ 26 27from keystoneauth1 import session 28from keystoneauth1 import token_endpoint 29from keystoneclient import exceptions as keystone_exceptions 30 31from openstack_auth import backend 32from openstack_auth import utils as auth_utils 33 34from horizon import exceptions 35 36from openstack_dashboard.api import base 37from openstack_dashboard.contrib.developer.profiler import api as profiler 38from openstack_dashboard import policy 39from openstack_dashboard.utils import settings as setting_utils 40 41 42LOG = logging.getLogger(__name__) 43DEFAULT_ROLE = None 44DEFAULT_DOMAIN = settings.OPENSTACK_KEYSTONE_DEFAULT_DOMAIN 45 46 47# Set up our data structure for managing Identity API versions, and 48# add a couple utility methods to it. 49class IdentityAPIVersionManager(base.APIVersionManager): 50 def upgrade_v2_user(self, user): 51 if getattr(user, "project_id", None) is None: 52 user.project_id = getattr(user, "default_project_id", 53 getattr(user, "tenantId", None)) 54 return user 55 56 def get_project_manager(self, *args, **kwargs): 57 return keystoneclient(*args, **kwargs).projects 58 59 60VERSIONS = IdentityAPIVersionManager( 61 "identity", preferred_version=auth_utils.get_keystone_version()) 62 63 64try: 65 # pylint: disable=ungrouped-imports 66 from keystoneclient.v3 import client as keystone_client_v3 67 VERSIONS.load_supported_version(3, {"client": keystone_client_v3}) 68except ImportError: 69 pass 70 71 72class Service(base.APIDictWrapper): 73 """Wrapper for a dict based on the service data from keystone.""" 74 _attrs = ['id', 'type', 'name'] 75 76 def __init__(self, service, region, *args, **kwargs): 77 super().__init__(service, *args, **kwargs) 78 self.public_url = base.get_url_for_service(service, region, 79 'publicURL') 80 self.url = base.get_url_for_service(service, region, 81 settings.OPENSTACK_ENDPOINT_TYPE) 82 if self.url: 83 self.host = parse.urlparse(self.url).hostname 84 else: 85 self.host = None 86 self.disabled = None 87 self.region = region 88 89 def __str__(self): 90 if(self.type == "identity"): 91 return _("%(type)s (%(backend)s backend)") \ 92 % {"type": self.type, "backend": keystone_backend_name()} 93 return self.type 94 95 def __repr__(self): 96 return "<Service: %s>" % self 97 98 99def _get_endpoint_url(request, endpoint_type, catalog=None): 100 if getattr(request.user, "service_catalog", None): 101 url = base.url_for(request, 102 service_type='identity', 103 endpoint_type=endpoint_type) 104 message = ("The Keystone URL in service catalog points to a v2.0 " 105 "Keystone endpoint, but v3 is specified as the API version " 106 "to use by Horizon. Using v3 endpoint for authentication.") 107 else: 108 auth_url = settings.OPENSTACK_KEYSTONE_URL 109 url = request.session.get('region_endpoint', auth_url) 110 message = ("The OPENSTACK_KEYSTONE_URL setting points to a v2.0 " 111 "Keystone endpoint, but v3 is specified as the API version " 112 "to use by Horizon. Using v3 endpoint for authentication.") 113 114 # TODO(gabriel): When the Service Catalog no longer contains API versions 115 # in the endpoints this can be removed. 116 url, url_fixed = auth_utils.fix_auth_url_version_prefix(url) 117 if url_fixed: 118 LOG.warning(message) 119 120 return url 121 122 123def keystoneclient(request, admin=False): 124 """Returns a client connected to the Keystone backend. 125 126 Several forms of authentication are supported: 127 128 * Username + password -> Unscoped authentication 129 * Username + password + tenant id -> Scoped authentication 130 * Unscoped token -> Unscoped authentication 131 * Unscoped token + tenant id -> Scoped authentication 132 * Scoped token -> Scoped authentication 133 134 Available services and data from the backend will vary depending on 135 whether the authentication was scoped or unscoped. 136 137 Lazy authentication if an ``endpoint`` parameter is provided. 138 139 Calls requiring the admin endpoint should have ``admin=True`` passed in 140 as a keyword argument. 141 142 The client is cached so that subsequent API calls during the same 143 request/response cycle don't have to be re-authenticated. 144 """ 145 client_version = VERSIONS.get_active_version() 146 user = request.user 147 token_id = user.token.id 148 149 if settings.OPENSTACK_KEYSTONE_MULTIDOMAIN_SUPPORT: 150 is_domain_context_specified = bool( 151 request.session.get("domain_context")) 152 153 # If user is Cloud Admin, Domain Admin or Mixed Domain Admin and there 154 # is no domain context specified, use domain scoped token 155 if is_domain_admin(request) and not is_domain_context_specified: 156 domain_token = request.session.get('domain_token') 157 if domain_token: 158 token_id = getattr(domain_token, 'auth_token', None) 159 160 if admin: 161 if not policy.check((("identity", "admin_required"),), request): 162 raise exceptions.NotAuthorized 163 endpoint_type = 'adminURL' 164 else: 165 endpoint_type = settings.OPENSTACK_ENDPOINT_TYPE 166 167 # Take care of client connection caching/fetching a new client. 168 # Admin vs. non-admin clients are cached separately for token matching. 169 cache_attr = "_keystoneclient_admin" if admin \ 170 else backend.KEYSTONE_CLIENT_ATTR 171 if (hasattr(request, cache_attr) and 172 (not user.token.id or 173 getattr(request, cache_attr).auth_token == user.token.id)): 174 conn = getattr(request, cache_attr) 175 else: 176 endpoint = _get_endpoint_url(request, endpoint_type) 177 verify = not settings.OPENSTACK_SSL_NO_VERIFY 178 cacert = settings.OPENSTACK_SSL_CACERT 179 verify = verify and cacert 180 LOG.debug("Creating a new keystoneclient connection to %s.", endpoint) 181 remote_addr = request.environ.get('REMOTE_ADDR', '') 182 token_auth = token_endpoint.Token(endpoint=endpoint, 183 token=token_id) 184 keystone_session = session.Session(auth=token_auth, 185 original_ip=remote_addr, 186 verify=verify) 187 conn = client_version['client'].Client(session=keystone_session, 188 debug=settings.DEBUG) 189 setattr(request, cache_attr, conn) 190 return conn 191 192 193@profiler.trace 194def get_identity_api_version(request): 195 client = keystoneclient(request) 196 endpoint_data = client.session.get_endpoint_data(service_type='identity') 197 return endpoint_data.api_version 198 199 200@profiler.trace 201def domain_create(request, name, description=None, enabled=None): 202 manager = keystoneclient(request, admin=True).domains 203 return manager.create(name=name, 204 description=description, 205 enabled=enabled) 206 207 208@profiler.trace 209def domain_get(request, domain_id): 210 manager = keystoneclient(request, admin=True).domains 211 return manager.get(domain_id) 212 213 214@profiler.trace 215def domain_delete(request, domain_id): 216 manager = keystoneclient(request, admin=True).domains 217 manager.delete(domain_id) 218 219 220@profiler.trace 221def domain_list(request): 222 manager = keystoneclient(request, admin=True).domains 223 return manager.list() 224 225 226def domain_lookup(request): 227 if policy.check((("identity", "identity:list_domains"),), request) \ 228 and request.session.get('domain_token'): 229 try: 230 domains = domain_list(request) 231 return dict((d.id, d.name) for d in domains) 232 except Exception: 233 LOG.warning("Pure project admin doesn't have a domain token") 234 return {} 235 else: 236 domain = get_default_domain(request) 237 return {domain.id: domain.name} 238 239 240@profiler.trace 241def domain_update(request, domain_id, name=None, description=None, 242 enabled=None): 243 manager = keystoneclient(request, admin=True).domains 244 try: 245 response = manager.update(domain_id, name=name, 246 description=description, enabled=enabled) 247 except Exception: 248 LOG.exception("Unable to update Domain: %s", domain_id) 249 raise 250 return response 251 252 253@profiler.trace 254def tenant_create(request, name, description=None, enabled=None, 255 domain=None, **kwargs): 256 manager = VERSIONS.get_project_manager(request, admin=True) 257 try: 258 return manager.create(name, domain, 259 description=description, 260 enabled=enabled, **kwargs) 261 except keystone_exceptions.Conflict: 262 raise exceptions.Conflict() 263 264 265def get_default_domain(request, get_name=True): 266 """Gets the default domain object to use when creating Identity object. 267 268 Returns the domain context if is set, otherwise return the domain 269 of the logon user. 270 271 :param get_name: Whether to get the domain name from Keystone if the 272 context isn't set. Setting this to False prevents an unnecessary call 273 to Keystone if only the domain ID is needed. 274 """ 275 domain_id = request.session.get("domain_context", None) 276 domain_name = request.session.get("domain_context_name", None) 277 if domain_id is None: 278 # if no domain context set, default to user's domain 279 domain_id = request.user.user_domain_id 280 domain_name = request.user.user_domain_name 281 if get_name and not request.user.is_federated: 282 try: 283 domain = domain_get(request, domain_id) 284 domain_name = domain.name 285 except exceptions.NotAuthorized: 286 # NOTE (knasim-wrs): Retrieving domain information 287 # is an admin URL operation. As a pre-check, such 288 # operations would be Forbidden if the logon user does 289 # not have an 'admin' role on the current project. 290 # 291 # Since this can be a common occurence and can cause 292 # incessant warning logging in the horizon logs, 293 # we recognize this condition and return the user's 294 # domain information instead. 295 LOG.debug("Cannot retrieve domain information for " 296 "user (%(user)s) that does not have an admin role " 297 "on project (%(project)s)", 298 {'user': request.user.username, 299 'project': request.user.project_name}) 300 except Exception: 301 LOG.warning("Unable to retrieve Domain: %s", domain_id) 302 domain = base.APIDictWrapper({"id": domain_id, 303 "name": domain_name}) 304 return domain 305 306 307def get_effective_domain_id(request): 308 """Gets the id of the default domain. 309 310 If the requests default domain is the same as DEFAULT_DOMAIN, 311 return None. 312 """ 313 default_domain = get_default_domain(request) 314 domain_id = default_domain.get('id') 315 domain_name = default_domain.get('name') 316 return None if domain_name == DEFAULT_DOMAIN else domain_id 317 318 319def is_cloud_admin(request): 320 return policy.check((("identity", "cloud_admin"),), request) 321 322 323def is_domain_admin(request): 324 return policy.check( 325 (("identity", "admin_and_matching_domain_id"),), request) 326 327 328# TODO(gabriel): Is there ever a valid case for admin to be false here? 329# A quick search through the codebase reveals that it's always called with 330# admin=true so I suspect we could eliminate it entirely as with the other 331# tenant commands. 332@profiler.trace 333def tenant_get(request, project, admin=True): 334 manager = VERSIONS.get_project_manager(request, admin=admin) 335 try: 336 return manager.get(project) 337 except keystone_exceptions.NotFound: 338 LOG.info("Tenant '%s' not found.", project) 339 raise 340 341 342@profiler.trace 343def tenant_delete(request, project): 344 manager = VERSIONS.get_project_manager(request, admin=True) 345 manager.delete(project) 346 347 348@profiler.trace 349def tenant_list(request, paginate=False, marker=None, domain=None, user=None, 350 admin=True, filters=None): 351 manager = VERSIONS.get_project_manager(request, admin=admin) 352 tenants = [] 353 has_more_data = False 354 355 # if requesting the projects for the current user, 356 # return the list from the cache 357 if user == request.user.id: 358 tenants = request.user.authorized_tenants 359 else: 360 domain_id = get_effective_domain_id(request) 361 kwargs = { 362 "domain": domain_id, 363 "user": user 364 } 365 if filters is not None: 366 kwargs.update(filters) 367 if 'id' in kwargs: 368 try: 369 tenants = [tenant_get(request, kwargs['id'])] 370 except keystone_exceptions.NotFound: 371 tenants = [] 372 except Exception: 373 exceptions.handle(request) 374 else: 375 tenants = manager.list(**kwargs) 376 return tenants, has_more_data 377 378 379@profiler.trace 380def tenant_update(request, project, name=None, description=None, 381 enabled=None, domain=None, **kwargs): 382 manager = VERSIONS.get_project_manager(request, admin=True) 383 try: 384 return manager.update(project, name=name, description=description, 385 enabled=enabled, domain=domain, **kwargs) 386 except keystone_exceptions.Conflict: 387 raise exceptions.Conflict() 388 389 390@profiler.trace 391def user_list(request, project=None, domain=None, group=None, filters=None): 392 users = [] 393 kwargs = { 394 "project": project, 395 "domain": domain, 396 "group": group 397 } 398 if filters is not None: 399 kwargs.update(filters) 400 if 'id' in kwargs: 401 try: 402 users = [user_get(request, kwargs['id'])] 403 except keystone_exceptions.NotFound: 404 raise exceptions.NotFound() 405 else: 406 users = keystoneclient(request, admin=True).users.list(**kwargs) 407 return [VERSIONS.upgrade_v2_user(user) for user in users] 408 409 410@profiler.trace 411def user_create(request, name=None, email=None, password=None, project=None, 412 enabled=None, domain=None, description=None, **data): 413 manager = keystoneclient(request, admin=True).users 414 try: 415 return manager.create(name, password=password, email=email, 416 default_project=project, enabled=enabled, 417 domain=domain, description=description, 418 **data) 419 except keystone_exceptions.Conflict: 420 raise exceptions.Conflict() 421 422 423@profiler.trace 424def user_delete(request, user_id): 425 keystoneclient(request, admin=True).users.delete(user_id) 426 427 428@profiler.trace 429def user_get(request, user_id, admin=True): 430 user = keystoneclient(request, admin=admin).users.get(user_id) 431 return VERSIONS.upgrade_v2_user(user) 432 433 434@profiler.trace 435def user_update(request, user, **data): 436 manager = keystoneclient(request, admin=True).users 437 438 if not keystone_can_edit_user(): 439 raise keystone_exceptions.ClientException( 440 _("Identity service does not allow editing user data.")) 441 try: 442 user = manager.update(user, **data) 443 except keystone_exceptions.Conflict: 444 raise exceptions.Conflict() 445 446 447@profiler.trace 448def user_update_enabled(request, user, enabled): 449 manager = keystoneclient(request, admin=True).users 450 manager.update(user, enabled=enabled) 451 452 453@profiler.trace 454def user_update_password(request, user, password, admin=True): 455 456 if not keystone_can_edit_user(): 457 raise keystone_exceptions.ClientException( 458 _("Identity service does not allow editing user password.")) 459 460 manager = keystoneclient(request, admin=admin).users 461 manager.update(user, password=password) 462 463 464def user_verify_admin_password(request, admin_password): 465 # attempt to create a new client instance with admin password to 466 # verify if it's correct. 467 client = keystone_client_v3 468 try: 469 endpoint = _get_endpoint_url(request, 'publicURL') 470 insecure = settings.OPENSTACK_SSL_NO_VERIFY 471 cacert = settings.OPENSTACK_SSL_CACERT 472 client.Client( 473 username=request.user.username, 474 password=admin_password, 475 insecure=insecure, 476 cacert=cacert, 477 auth_url=endpoint 478 ) 479 return True 480 except Exception: 481 exceptions.handle(request, ignore=True) 482 return False 483 484 485@profiler.trace 486def user_update_own_password(request, origpassword, password): 487 client = keystoneclient(request, admin=False) 488 client.users.client.session.auth.user_id = request.user.id 489 return client.users.update_password(origpassword, password) 490 491 492@profiler.trace 493def user_update_tenant(request, user, project, admin=True): 494 manager = keystoneclient(request, admin=admin).users 495 return manager.update(user, project=project) 496 497 498@profiler.trace 499def group_create(request, domain_id, name, description=None): 500 manager = keystoneclient(request, admin=True).groups 501 try: 502 return manager.create(domain=domain_id, 503 name=name, 504 description=description) 505 except keystone_exceptions.Conflict: 506 raise exceptions.Conflict() 507 508 509@profiler.trace 510def group_get(request, group_id, admin=True): 511 manager = keystoneclient(request, admin=admin).groups 512 return manager.get(group_id) 513 514 515@profiler.trace 516def group_delete(request, group_id): 517 manager = keystoneclient(request, admin=True).groups 518 return manager.delete(group_id) 519 520 521@profiler.trace 522def group_list(request, domain=None, project=None, user=None, filters=None): 523 manager = keystoneclient(request, admin=True).groups 524 groups = [] 525 kwargs = { 526 "domain": domain, 527 "user": user, 528 "name": None 529 } 530 if filters is not None: 531 kwargs.update(filters) 532 if 'id' in kwargs: 533 try: 534 groups = [manager.get(kwargs['id'])] 535 except keystone_exceptions.NotFound: 536 raise exceptions.NotFound() 537 else: 538 groups = manager.list(**kwargs) 539 540 if project: 541 project_groups = [] 542 for group in groups: 543 roles = roles_for_group(request, group=group.id, project=project) 544 if roles: 545 project_groups.append(group) 546 groups = project_groups 547 return groups 548 549 550@profiler.trace 551def group_update(request, group_id, name=None, description=None): 552 manager = keystoneclient(request, admin=True).groups 553 try: 554 return manager.update(group=group_id, 555 name=name, 556 description=description) 557 except keystone_exceptions.Conflict: 558 raise exceptions.Conflict() 559 560 561@profiler.trace 562def add_group_user(request, group_id, user_id): 563 manager = keystoneclient(request, admin=True).users 564 return manager.add_to_group(group=group_id, user=user_id) 565 566 567@profiler.trace 568def remove_group_user(request, group_id, user_id): 569 manager = keystoneclient(request, admin=True).users 570 return manager.remove_from_group(group=group_id, user=user_id) 571 572 573def get_project_groups_roles(request, project): 574 """Gets the groups roles in a given project. 575 576 :param request: the request entity containing the login user information 577 :param project: the project to filter the groups roles. It accepts both 578 project object resource or project ID 579 580 :returns group_roles: a dictionary mapping the groups and their roles in 581 given project 582 583 """ 584 groups_roles = collections.defaultdict(list) 585 project_role_assignments = role_assignments_list(request, 586 project=project) 587 588 for role_assignment in project_role_assignments: 589 if not hasattr(role_assignment, 'group'): 590 continue 591 group_id = role_assignment.group['id'] 592 role_id = role_assignment.role['id'] 593 594 # filter by project_id 595 if ('project' in role_assignment.scope and 596 role_assignment.scope['project']['id'] == project): 597 groups_roles[group_id].append(role_id) 598 return groups_roles 599 600 601@profiler.trace 602def role_assignments_list(request, project=None, user=None, role=None, 603 group=None, domain=None, effective=False, 604 include_subtree=True, include_names=False): 605 if include_subtree: 606 domain = None 607 608 manager = keystoneclient(request, admin=True).role_assignments 609 610 return manager.list(project=project, user=user, role=role, group=group, 611 domain=domain, effective=effective, 612 include_subtree=include_subtree, 613 include_names=include_names) 614 615 616@profiler.trace 617def role_create(request, name): 618 manager = keystoneclient(request, admin=True).roles 619 return manager.create(name) 620 621 622@profiler.trace 623def role_get(request, role_id): 624 manager = keystoneclient(request, admin=True).roles 625 return manager.get(role_id) 626 627 628@profiler.trace 629def role_update(request, role_id, name=None): 630 manager = keystoneclient(request, admin=True).roles 631 return manager.update(role_id, name) 632 633 634@profiler.trace 635def role_delete(request, role_id): 636 manager = keystoneclient(request, admin=True).roles 637 manager.delete(role_id) 638 639 640@profiler.trace 641def role_list(request, filters=None): 642 """Returns a global list of available roles.""" 643 manager = keystoneclient(request, admin=True).roles 644 roles = [] 645 kwargs = {} 646 if filters is not None: 647 kwargs.update(filters) 648 if 'id' in kwargs: 649 try: 650 roles = [manager.get(kwargs['id'])] 651 except keystone_exceptions.NotFound: 652 roles = [] 653 except Exception: 654 exceptions.handle(request) 655 else: 656 roles = manager.list(**kwargs) 657 return roles 658 659 660@profiler.trace 661def roles_for_user(request, user, project=None, domain=None): 662 """Returns a list of user roles scoped to a project or domain.""" 663 manager = keystoneclient(request, admin=True).roles 664 return manager.list(user=user, domain=domain, project=project) 665 666 667@profiler.trace 668def get_domain_users_roles(request, domain): 669 users_roles = collections.defaultdict(list) 670 domain_role_assignments = role_assignments_list(request, 671 domain=domain, 672 include_subtree=False) 673 for role_assignment in domain_role_assignments: 674 if not hasattr(role_assignment, 'user'): 675 continue 676 user_id = role_assignment.user['id'] 677 role_id = role_assignment.role['id'] 678 679 # filter by domain_id 680 if ('domain' in role_assignment.scope and 681 role_assignment.scope['domain']['id'] == domain): 682 users_roles[user_id].append(role_id) 683 return users_roles 684 685 686@profiler.trace 687def add_domain_user_role(request, user, role, domain): 688 """Adds a role for a user on a domain.""" 689 manager = keystoneclient(request, admin=True).roles 690 return manager.grant(role, user=user, domain=domain) 691 692 693@profiler.trace 694def remove_domain_user_role(request, user, role, domain=None): 695 """Removes a given single role for a user from a domain.""" 696 manager = keystoneclient(request, admin=True).roles 697 return manager.revoke(role, user=user, domain=domain) 698 699 700@profiler.trace 701def get_project_users_roles(request, project): 702 users_roles = collections.defaultdict(list) 703 project_role_assignments = role_assignments_list(request, 704 project=project) 705 for role_assignment in project_role_assignments: 706 if not hasattr(role_assignment, 'user'): 707 continue 708 user_id = role_assignment.user['id'] 709 role_id = role_assignment.role['id'] 710 711 # filter by project_id 712 if ('project' in role_assignment.scope and 713 role_assignment.scope['project']['id'] == project): 714 users_roles[user_id].append(role_id) 715 return users_roles 716 717 718@profiler.trace 719def add_tenant_user_role(request, project=None, user=None, role=None, 720 group=None, domain=None): 721 """Adds a role for a user on a tenant.""" 722 manager = keystoneclient(request, admin=True).roles 723 manager.grant(role, user=user, project=project, 724 group=group, domain=domain) 725 726 727@profiler.trace 728def remove_tenant_user_role(request, project=None, user=None, role=None, 729 group=None, domain=None): 730 """Removes a given single role for a user from a tenant.""" 731 manager = keystoneclient(request, admin=True).roles 732 return manager.revoke(role, user=user, project=project, 733 group=group, domain=domain) 734 735 736def remove_tenant_user(request, project=None, user=None, domain=None): 737 """Removes all roles from a user on a tenant, removing them from it.""" 738 client = keystoneclient(request, admin=True) 739 roles = client.roles.roles_for_user(user, project) 740 for role in roles: 741 remove_tenant_user_role(request, user=user, role=role.id, 742 project=project, domain=domain) 743 744 745@profiler.trace 746def roles_for_group(request, group, domain=None, project=None): 747 manager = keystoneclient(request, admin=True).roles 748 return manager.list(group=group, domain=domain, project=project) 749 750 751@profiler.trace 752def add_group_role(request, role, group, domain=None, project=None): 753 """Adds a role for a group on a domain or project.""" 754 manager = keystoneclient(request, admin=True).roles 755 return manager.grant(role=role, group=group, domain=domain, 756 project=project) 757 758 759@profiler.trace 760def remove_group_role(request, role, group, domain=None, project=None): 761 """Removes a given single role for a group from a domain or project.""" 762 manager = keystoneclient(request, admin=True).roles 763 return manager.revoke(role=role, group=group, project=project, 764 domain=domain) 765 766 767@profiler.trace 768def remove_group_roles(request, group, domain=None, project=None): 769 """Removes all roles from a group on a domain or project.""" 770 client = keystoneclient(request, admin=True) 771 roles = client.roles.list(group=group, domain=domain, project=project) 772 for role in roles: 773 remove_group_role(request, role=role.id, group=group, 774 domain=domain, project=project) 775 776 777def get_default_role(request): 778 """Gets the default role object from Keystone and saves it as a global. 779 780 Since this is configured in settings and should not change from request 781 to request. Supports lookup by name or id. 782 """ 783 global DEFAULT_ROLE 784 default = settings.OPENSTACK_KEYSTONE_DEFAULT_ROLE 785 if default and DEFAULT_ROLE is None: 786 try: 787 roles = keystoneclient(request, admin=True).roles.list() 788 except Exception: 789 roles = [] 790 exceptions.handle(request) 791 for role in roles: 792 if default in (role.id, role.name): 793 DEFAULT_ROLE = role 794 break 795 return DEFAULT_ROLE 796 797 798def ec2_manager(request): 799 client = keystoneclient(request) 800 if hasattr(client, 'ec2'): 801 return client.ec2 802 803 from keystoneclient.v3 import ec2 804 return ec2.EC2Manager(client) 805 806 807@profiler.trace 808def list_ec2_credentials(request, user_id): 809 return ec2_manager(request).list(user_id) 810 811 812@profiler.trace 813def create_ec2_credentials(request, user_id, tenant_id): 814 return ec2_manager(request).create(user_id, tenant_id) 815 816 817@profiler.trace 818def get_user_ec2_credentials(request, user_id, access_token): 819 return ec2_manager(request).get(user_id, access_token) 820 821 822@profiler.trace 823def delete_user_ec2_credentials(request, user_id, access_token): 824 return ec2_manager(request).delete(user_id, access_token) 825 826 827def keystone_can_edit_domain(): 828 can_edit_domain = setting_utils.get_dict_config( 829 'OPENSTACK_KEYSTONE_BACKEND', 'can_edit_domain') 830 multi_domain_support = settings.OPENSTACK_KEYSTONE_MULTIDOMAIN_SUPPORT 831 return can_edit_domain and multi_domain_support 832 833 834def keystone_can_edit_user(): 835 return setting_utils.get_dict_config( 836 'OPENSTACK_KEYSTONE_BACKEND', 'can_edit_user') 837 838 839def keystone_can_edit_project(): 840 return setting_utils.get_dict_config( 841 'OPENSTACK_KEYSTONE_BACKEND', 'can_edit_project') 842 843 844def keystone_can_edit_group(): 845 return setting_utils.get_dict_config( 846 'OPENSTACK_KEYSTONE_BACKEND', 'can_edit_group') 847 848 849def keystone_can_edit_role(): 850 return setting_utils.get_dict_config( 851 'OPENSTACK_KEYSTONE_BACKEND', 'can_edit_role') 852 853 854def keystone_backend_name(): 855 return setting_utils.get_dict_config( 856 'OPENSTACK_KEYSTONE_BACKEND', 'name') or 'unknown' 857 858 859def get_version(): 860 return VERSIONS.active 861 862 863def identity_provider_create(request, idp_id, description=None, 864 enabled=False, remote_ids=None): 865 manager = keystoneclient(request, admin=True).federation.identity_providers 866 try: 867 return manager.create(id=idp_id, 868 description=description, 869 enabled=enabled, 870 remote_ids=remote_ids) 871 except keystone_exceptions.Conflict: 872 raise exceptions.Conflict() 873 874 875@profiler.trace 876def identity_provider_get(request, idp_id): 877 manager = keystoneclient(request, admin=True).federation.identity_providers 878 return manager.get(idp_id) 879 880 881@profiler.trace 882def identity_provider_update(request, idp_id, description=None, 883 enabled=False, remote_ids=None): 884 manager = keystoneclient(request, admin=True).federation.identity_providers 885 try: 886 return manager.update(idp_id, 887 description=description, 888 enabled=enabled, 889 remote_ids=remote_ids) 890 except keystone_exceptions.Conflict: 891 raise exceptions.Conflict() 892 893 894@profiler.trace 895def identity_provider_delete(request, idp_id): 896 manager = keystoneclient(request, admin=True).federation.identity_providers 897 return manager.delete(idp_id) 898 899 900@profiler.trace 901def identity_provider_list(request): 902 manager = keystoneclient(request, admin=True).federation.identity_providers 903 return manager.list() 904 905 906@profiler.trace 907def mapping_create(request, mapping_id, rules): 908 manager = keystoneclient(request, admin=True).federation.mappings 909 try: 910 return manager.create(mapping_id=mapping_id, rules=rules) 911 except keystone_exceptions.Conflict: 912 raise exceptions.Conflict() 913 914 915@profiler.trace 916def mapping_get(request, mapping_id): 917 manager = keystoneclient(request, admin=True).federation.mappings 918 return manager.get(mapping_id) 919 920 921@profiler.trace 922def mapping_update(request, mapping_id, rules): 923 manager = keystoneclient(request, admin=True).federation.mappings 924 return manager.update(mapping_id, rules=rules) 925 926 927@profiler.trace 928def mapping_delete(request, mapping_id): 929 manager = keystoneclient(request, admin=True).federation.mappings 930 return manager.delete(mapping_id) 931 932 933@profiler.trace 934def mapping_list(request): 935 manager = keystoneclient(request, admin=True).federation.mappings 936 return manager.list() 937 938 939@profiler.trace 940def protocol_create(request, protocol_id, identity_provider, mapping): 941 manager = keystoneclient(request).federation.protocols 942 try: 943 return manager.create(protocol_id, identity_provider, mapping) 944 except keystone_exceptions.Conflict: 945 raise exceptions.Conflict() 946 947 948@profiler.trace 949def protocol_get(request, identity_provider, protocol): 950 manager = keystoneclient(request).federation.protocols 951 return manager.get(identity_provider, protocol) 952 953 954@profiler.trace 955def protocol_update(request, identity_provider, protocol, mapping): 956 manager = keystoneclient(request).federation.protocols 957 return manager.update(identity_provider, protocol, mapping) 958 959 960@profiler.trace 961def protocol_delete(request, identity_provider, protocol): 962 manager = keystoneclient(request).federation.protocols 963 return manager.delete(identity_provider, protocol) 964 965 966@profiler.trace 967def protocol_list(request, identity_provider): 968 manager = keystoneclient(request).federation.protocols 969 return manager.list(identity_provider) 970 971 972@profiler.trace 973def application_credential_list(request, filters=None): 974 user = request.user.id 975 manager = keystoneclient(request).application_credentials 976 return manager.list(user=user, **filters) 977 978 979@profiler.trace 980def application_credential_get(request, application_credential_id): 981 user = request.user.id 982 manager = keystoneclient(request).application_credentials 983 return manager.get(application_credential=application_credential_id, 984 user=user) 985 986 987@profiler.trace 988def application_credential_delete(request, application_credential_id): 989 user = request.user.id 990 manager = keystoneclient(request).application_credentials 991 return manager.delete(application_credential=application_credential_id, 992 user=user) 993 994 995@profiler.trace 996def application_credential_create(request, name, secret=None, 997 description=None, expires_at=None, 998 roles=None, unrestricted=False, 999 access_rules=None): 1000 user = request.user.id 1001 manager = keystoneclient(request).application_credentials 1002 try: 1003 return manager.create(name=name, user=user, secret=secret, 1004 description=description, expires_at=expires_at, 1005 roles=roles, unrestricted=unrestricted, 1006 access_rules=access_rules) 1007 except keystone_exceptions.Conflict: 1008 raise exceptions.Conflict() 1009