From 2ad03f81400e1c598892094f2ed29f455f12d1bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20P=C3=A9ters?= Date: Mon, 12 Aug 2019 16:30:33 +0200 Subject: [PATCH] authentic agent: remove obsolete import-wcs-roles command (#35374) --- README | 6 - .../management/commands/import-wcs-roles.py | 202 ------------------ 2 files changed, 208 deletions(-) delete mode 100644 hobo/agent/authentic2/management/commands/import-wcs-roles.py diff --git a/README b/README index 3df0031..e96287e 100644 --- a/README +++ b/README @@ -156,12 +156,6 @@ adapted in the AUTHENTIC_MANAGE_COMMAND setting. It should be run with the same rights as the authentic2 process (redefine the command to use sudo if necessary). -The agent also provide a commands to import roles from w.c.s named -import-wcs-roles. It computes the web-service credentials from the hobo.json -and use the email of the oldest superuser. Cron job can be created for calling -this command when regular synchronization of roles with your w.c.s. instances -is needed. The sole option named "--delete" indicate if you want to delete -stale roles, default is to not delete them. Tests ----- diff --git a/hobo/agent/authentic2/management/commands/import-wcs-roles.py b/hobo/agent/authentic2/management/commands/import-wcs-roles.py deleted file mode 100644 index 2ba2e64..0000000 --- a/hobo/agent/authentic2/management/commands/import-wcs-roles.py +++ /dev/null @@ -1,202 +0,0 @@ -# hobo - portal to configure and deploy applications -# Copyright (C) 2015 Entr'ouvert -# -# 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 . - -import os -import logging -import requests -import urllib -import urlparse -import hashlib -import json - -from optparse import make_option - -from django.utils.text import slugify -from django.core.management.base import BaseCommand -from django.utils.translation import ugettext as _ -from django.conf import settings - -from authentic2.saml.models import LibertyProvider -from authentic2.a2_rbac.models import Role, RoleAttribute -from authentic2 import app_settings - - -from hobo import signature -from hobo.multitenant.middleware import TenantMiddleware - -from tenant_schemas.utils import tenant_context - - -class WcsRoleImporter(object): - def __init__(self, liberty_provider, key, orig, - attribute_name='role-slug', delete=False): - self.service = liberty_provider - self.slug = liberty_provider.slug - self.key = key - self.orig = orig - self.attribute_name = attribute_name - self.delete = delete - assert 'saml/metadata' in self.service.entity_id - self.wcs_url = self.service.entity_id.split('saml/metadata')[0] - self.logger = logging.getLogger('%s.%s' % (__name__, - self.__class__.__name__)) - self.seen_ids = set() - - def import_roles(self): - for role_tpl in self.get_roles(): - self.seen_ids.add(role_tpl.external_id) - self.create_role(role_tpl) - if self.delete: - self.delete_dead_roles() - su_role, created = Role.objects.get_or_create( - service=self.service, slug='_a2-hobo-superuser', - defaults={'name': _('Superuser')}) - su_role.attributes.get_or_create(name='is_superuser', kind='string', - value='true') - - def create_role(self, role_tpl): - defaults = { - 'name': role_tpl.name, - # w.c.s. will always provide a slug but for other services we do - # not know - 'slug': role_tpl.slug or slugify(role_tpl.name), - } - # search role by external id, create if not found - role, created = Role.objects.get_or_create( - ou=self.service.ou, - external_id=role_tpl.external_id, - defaults=defaults) - RoleAttribute.objects.filter(role=role).delete() - role_attribute, ra_created = RoleAttribute.objects.get_or_create( - role=role, - name=self.attribute_name, - kind='string', - defaults={ - 'value': role_tpl.external_id - }) - if created: - self.logger.info('imported new role %r(%r) from service %s', - role.external_id, role.name, self.slug) - # update role attribute value if it has changed - if not ra_created: - if role_attribute.value != role_tpl.external_id: - role_attribute.value = role_tpl.external_id - role_attribute.save() - # update role name if has changed - if not created: - # Update name and slug if they have changed - if role.name != role_tpl.name: - role.name = role_tpl.name - role.save() - # update emails, emails_to_members and details in RA - if role_tpl.emails: - ra, created = RoleAttribute.objects.get_or_create( - role=role, name='emails', kind='json', - defaults={'value': json.dumps(role_tpl.emails)}) - if ra.value != json.dumps(role_tpl.emails): - ra.value = json.dumps(role_tpl.emails) - ra.save() - ra, created = RoleAttribute.objects.get_or_create( - role=role, name='emails_to_members', kind='json', - defaults={'value': json.dumps(role_tpl.emails_to_members)}) - if ra.value != json.dumps(role_tpl.emails_to_members): - ra.value = json.dumps(role_tpl.emails_to_members) - ra.save() - if role_tpl.details: - value = json.dumps(role_tpl.details) - ra, created = RoleAttribute.objects.get_or_create( - role=role, name='details', kind='json', - defaults={'value': value}) - if ra.value != value: - ra.value = value - ra.save() - - def delete_dead_roles(self): - '''Deletes service roles whose id is not in self.seen_ids''' - qs = Role.objects.filter(service=self.service) \ - .exclude(external_id__in=list(self.seen_ids)) - for role in qs: - self.logger.info('deleted dead role %r(%r) from service %s', - role.external_id, role.slug, self.slug) - qs.delete() - - def get_roles(self): - '''Get w.c.s. from its roles web-service by sending a signed GET - request. - ''' - url = self.wcs_url + 'api/roles?%s' % urllib.urlencode( - {'format': 'json', 'orig': self.orig}) - signed_url = signature.sign_url(url, self.key) - response = requests.get(signed_url, verify=app_settings.A2_VERIFY_SSL) - if response.status_code == 200: - for role in response.json()['data']: - new_role = Role(name=role['text'], external_id=str(role['slug']), - slug=str(role['slug'])) - new_role.description = role.get('details', u'') - new_role.emails = role.get('emails', []) - new_role.emails_to_members = role.get('emails_to_members', False) - new_role.details = role.get('details', '') - yield new_role - else: - self.logger.warn('failed to get roles for %s (response: %s)', - self.wcs_url, response.status_code) - - -class Command(BaseCommand): - help = "Import W.C.S. roles" - - requires_system_checks = False - - def add_arguments(self, parser): - parser.add_argument('--delete', action="store_true", dest='delete') - - def handle(self, *args, **options): - # traverse list of tenants - for tenant in TenantMiddleware.get_tenants(): - with tenant_context(tenant): - if getattr(settings, 'HOBO_ROLE_EXPORT', True): - continue - self.handle_tenant(tenant, **options) - - def handle_tenant(self, tenant, **options): - # extract informations on deployed w.c.s. instances from hobo.json - hobo_json_path = os.path.join(tenant.get_directory(), 'hobo.json') - if not os.path.exists(hobo_json_path): - print 'skipping %s, no hobo.json found' % tenant - return - hobo_environment = json.load(open(hobo_json_path)) - # compute our credentials from our hobo configuration - me = [x for x in hobo_environment['services'] if x.get('this')] - if not me: - print 'skipping %s, self services is not marked' % tenant - return - me = me[0] - orig = urlparse.urlsplit(me['base_url']).netloc.split(':')[0] - for service_id in settings.KNOWN_SERVICES: - if service_id != 'wcs': - continue - for service in settings.KNOWN_SERVICES[service_id].values(): - if not service.get('secret'): - continue - liberty_provider = LibertyProvider.objects.get( - entity_id=service['url'] + 'saml/metadata') - importer = WcsRoleImporter( - liberty_provider=liberty_provider, - key=service['secret'], - orig=orig, - delete=options.get('delete', False), - ) - importer.import_roles()