authentic agent: remove obsolete import-wcs-roles command (#35374)

This commit is contained in:
Frédéric Péters 2019-08-12 16:30:33 +02:00
parent 4c39a9d35f
commit 2ad03f8140
2 changed files with 0 additions and 208 deletions

6
README
View File

@ -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
-----

View File

@ -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 <http://www.gnu.org/licenses/>.
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()