Subclass the SSSd info plugin for our use
Signed-off-by: Aurélien Bompard <aurelien@bompard.org>
This commit is contained in:
parent
1855c1c738
commit
9350937d54
2 changed files with 36 additions and 191 deletions
|
@ -7,5 +7,6 @@ SITE_PACKAGES=`python3 -Ic "from distutils.sysconfig import get_python_lib; prin
|
||||||
set -x
|
set -x
|
||||||
|
|
||||||
cp -afv ipsilon ${ROOT}${SITE_PACKAGES}/
|
cp -afv ipsilon ${ROOT}${SITE_PACKAGES}/
|
||||||
cat openid-server.patch | patch -p0 --fuzz 0 -d ${ROOT}${SITE_PACKAGES}/
|
python3 -m compileall ${ROOT}${SITE_PACKAGES}/ipsilon
|
||||||
python3 -m compileall ${ROOT}${SITE_PACKAGES}/{ipsilon,openid}
|
cat openid-server.patch | patch -p0 --fuzz 0 -d ${ROOT}${SITE_PACKAGES}/ -N
|
||||||
|
python3 -m compileall ${ROOT}${SITE_PACKAGES}/openid
|
||||||
|
|
|
@ -1,202 +1,46 @@
|
||||||
# Copyright (C) 2014,2016 Ipsilon project Contributors, for license see COPYING
|
|
||||||
|
|
||||||
from ipsilon.info.common import InfoProviderBase, InfoProviderInstaller
|
|
||||||
from ipsilon.util.plugin import PluginObject
|
|
||||||
from ipsilon.util.policy import Policy
|
|
||||||
from ipsilon.util import config as pconfig
|
from ipsilon.util import config as pconfig
|
||||||
|
from ipsilon.info.infosssd import InfoProvider as SSSDInfoProvider
|
||||||
from fedora.client.fas2 import AccountSystem
|
|
||||||
|
|
||||||
|
|
||||||
try:
|
AWS_IDP_ARN = "arn:aws:iam::125523088429:saml-provider/id.fedoraproject.org"
|
||||||
import openid_cla.cla as cla
|
AWS_GROUPS = {
|
||||||
|
"aws-master": "arn:aws:iam::125523088429:role/aws-master",
|
||||||
CLA_GROUPS = {
|
"aws-iam": "arn:aws:iam::125523088429:role/aws-iam",
|
||||||
'cla_click': cla.CLA_URI_FEDORA_CLICK,
|
"aws-billing": "arn:aws:iam::125523088429:role/aws-billing",
|
||||||
'cla_dell': cla.CLA_URI_FEDORA_DELL,
|
"aws-atomic": "arn:aws:iam::125523088429:role/aws-atomic",
|
||||||
'cla_done': cla.CLA_URI_FEDORA_DONE,
|
"aws-s3-readonly": "arn:aws:iam::125523088429:role/aws-s3-readonly",
|
||||||
'cla_fedora': cla.CLA_URI_FEDORA_FEDORA,
|
"aws-fedoramirror": "arn:aws:iam::125523088429:role/aws-fedoramirror",
|
||||||
'cla_fpca': cla.CLA_URI_FEDORA_FPCA,
|
"aws-s3": "arn:aws:iam::125523088429:role/aws-s3",
|
||||||
'cla_ibm': cla.CLA_URI_FEDORA_IBM,
|
"aws-cloud-poc": "arn:aws:iam::125523088429:role/aws-cloud-poc",
|
||||||
'cla_intel': cla.CLA_URI_FEDORA_INTEL,
|
"aws-infra": "arn:aws:iam::125523088429:role/aws-infra",
|
||||||
'cla_redhat': cla.CLA_URI_FEDORA_REDHAT,
|
"aws-docs": "arn:aws:iam::125523088429:role/aws-docs",
|
||||||
}
|
"aws-copr": "arn:aws:iam::125523088429:role/aws-copr",
|
||||||
except ImportError:
|
"aws-centos": "arn:aws:iam::125523088429:role/aws-centos",
|
||||||
CLA_GROUPS = dict()
|
"aws-min": "arn:aws:iam::125523088429:role/aws-min",
|
||||||
|
"aws-fedora-ci": "arn:aws:iam::125523088429:role/aws-fedora-ci",
|
||||||
fas_mapping = [
|
|
||||||
['username', 'nickname'],
|
|
||||||
['telephone', 'phone'],
|
|
||||||
['country_code', 'country'],
|
|
||||||
['human_name', 'fullname'],
|
|
||||||
['email', 'email'],
|
|
||||||
['timezone', 'timezone'],
|
|
||||||
['ssh_key', 'ssh_key'],
|
|
||||||
['gpg_keyid', 'gpg_keyid'],
|
|
||||||
]
|
|
||||||
|
|
||||||
fas_mapper = Policy(fas_mapping)
|
|
||||||
|
|
||||||
aws_idp_arn = 'arn:aws:iam::125523088429:saml-provider/id.fedoraproject.org'
|
|
||||||
aws_groups = {
|
|
||||||
'aws-master': 'arn:aws:iam::125523088429:role/aws-master',
|
|
||||||
'aws-iam': 'arn:aws:iam::125523088429:role/aws-iam',
|
|
||||||
'aws-billing': 'arn:aws:iam::125523088429:role/aws-billing',
|
|
||||||
'aws-atomic': 'arn:aws:iam::125523088429:role/aws-atomic',
|
|
||||||
'aws-s3-readonly': 'arn:aws:iam::125523088429:role/aws-s3-readonly',
|
|
||||||
'aws-fedoramirror': 'arn:aws:iam::125523088429:role/aws-fedoramirror',
|
|
||||||
'aws-s3': 'arn:aws:iam::125523088429:role/aws-s3',
|
|
||||||
'aws-cloud-poc': 'arn:aws:iam::125523088429:role/aws-cloud-poc',
|
|
||||||
'aws-infra': 'arn:aws:iam::125523088429:role/aws-infra',
|
|
||||||
'aws-docs': 'arn:aws:iam::125523088429:role/aws-docs',
|
|
||||||
'aws-copr': 'arn:aws:iam::125523088429:role/aws-copr',
|
|
||||||
'aws-centos': 'arn:aws:iam::125523088429:role/aws-centos',
|
|
||||||
'aws-min': 'arn:aws:iam::125523088429:role/aws-min',
|
|
||||||
'aws-fedora-ci': 'arn:aws:iam::125523088429:role/aws-fedora-ci',
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def fas_make_userdata(fas_data):
|
class InfoProvider(SSSDInfoProvider):
|
||||||
userdata, fas_extra = fas_mapper.map_attributes(fas_data)
|
def __init__(self, *kwargs):
|
||||||
|
super().__init__(*kwargs)
|
||||||
# We need to split ssh keys by newline, since we can't send newlines
|
self.name = "fas"
|
||||||
if userdata.get('ssh_key'):
|
|
||||||
userdata['ssh_key'] = userdata['ssh_key'].split('\n')
|
|
||||||
|
|
||||||
# compute and store groups and cla groups
|
|
||||||
userdata['_groups'] = []
|
|
||||||
userdata['_extras'] = {'fas': fas_extra, 'cla': []}
|
|
||||||
for group in fas_data.get('approved_memberships', {}):
|
|
||||||
if 'name' not in group:
|
|
||||||
continue
|
|
||||||
if group.get('group_type') == 'cla':
|
|
||||||
if group['name'] in CLA_GROUPS:
|
|
||||||
group_name = CLA_GROUPS[group['name']]
|
|
||||||
else:
|
|
||||||
group_name = group['name']
|
|
||||||
userdata['_extras']['cla'].append(group_name)
|
|
||||||
else:
|
|
||||||
userdata['_groups'].append(group['name'])
|
|
||||||
|
|
||||||
userdata['_extras']['awsroles'] = []
|
|
||||||
for group in userdata['_groups']:
|
|
||||||
if group in aws_groups:
|
|
||||||
userdata['_extras']['awsroles'].append(
|
|
||||||
'%s,%s' % (aws_idp_arn, aws_groups[group]))
|
|
||||||
|
|
||||||
return userdata
|
|
||||||
|
|
||||||
|
|
||||||
class InfoProvider(InfoProviderBase):
|
|
||||||
|
|
||||||
def __init__(self, *args):
|
|
||||||
super(InfoProvider, self).__init__(*args)
|
|
||||||
self._fas_client = None
|
|
||||||
self.name = 'fas'
|
|
||||||
self.description = """
|
self.description = """
|
||||||
Info plugin that retrieves user data from FAS. """
|
A Fedora-specific version of the SSSd info plugin.
|
||||||
|
"""
|
||||||
self.new_config(
|
self.new_config(
|
||||||
self.name,
|
self.name,
|
||||||
pconfig.String(
|
|
||||||
'FAS url',
|
|
||||||
'The FAS Url.',
|
|
||||||
'https://admin.fedoraproject.org/accounts/'),
|
|
||||||
pconfig.String(
|
|
||||||
'FAS Proxy client user Agent',
|
|
||||||
'The User Agent presented to the FAS Server.',
|
|
||||||
'Ipsilon v1.0'),
|
|
||||||
pconfig.Condition(
|
pconfig.Condition(
|
||||||
'FAS Insecure Auth',
|
"preconfigured", "SSSD can only be used when pre-configured", False
|
||||||
'If checked skips FAS server cert verification.',
|
),
|
||||||
False),
|
|
||||||
pconfig.String(
|
|
||||||
'Bind Username',
|
|
||||||
'Username to be used when retrieving info.',
|
|
||||||
'ipsilondummy'),
|
|
||||||
pconfig.String(
|
|
||||||
'Bind Password',
|
|
||||||
'Username to be used when retrieving info.',
|
|
||||||
'Password')
|
|
||||||
)
|
)
|
||||||
|
|
||||||
@property
|
|
||||||
def fas_url(self):
|
|
||||||
return self.get_config_value('FAS url')
|
|
||||||
|
|
||||||
@property
|
|
||||||
def user_agent(self):
|
|
||||||
return self.get_config_value('FAS Proxy client user Agent')
|
|
||||||
|
|
||||||
@property
|
|
||||||
def insecure(self):
|
|
||||||
return self.get_config_value('FAS Insecure Auth')
|
|
||||||
|
|
||||||
@property
|
|
||||||
def bind_user(self):
|
|
||||||
return self.get_config_value('Bind Username')
|
|
||||||
|
|
||||||
@property
|
|
||||||
def bind_pass(self):
|
|
||||||
return self.get_config_value('Bind Password')
|
|
||||||
|
|
||||||
@property
|
|
||||||
def fas_client(self):
|
|
||||||
if not self._fas_client:
|
|
||||||
self._fas_client = AccountSystem(base_url=self.fas_url,
|
|
||||||
insecure=self.insecure,
|
|
||||||
useragent=self.user_agent,
|
|
||||||
username=self.bind_user,
|
|
||||||
password=self.bind_pass)
|
|
||||||
return self._fas_client
|
|
||||||
|
|
||||||
def get_user_attrs(self, user):
|
def get_user_attrs(self, user):
|
||||||
if not self.fas_client:
|
reply = super().get_user_attrs(user)
|
||||||
return {}
|
reply["_extras"]["awsroles"] = []
|
||||||
try:
|
for group in reply["_groups"]:
|
||||||
data = self.fas_client.person_by_username(user)
|
if group in AWS_GROUPS:
|
||||||
except Exception as ex: # pylint: disable=broad-except
|
reply["_extras"]["awsroles"].append(
|
||||||
self.error('Unable to retrieve info for %s: %s' % (user, ex))
|
"%s,%s" % (AWS_IDP_ARN, AWS_GROUPS[group])
|
||||||
self.debug('URL: %s' % self.fas_url)
|
)
|
||||||
self.debug('username: %s' % self.bind_user)
|
return reply
|
||||||
return {}
|
|
||||||
if not data:
|
|
||||||
return {}
|
|
||||||
return fas_make_userdata(data)
|
|
||||||
|
|
||||||
|
|
||||||
class Installer(InfoProviderInstaller):
|
|
||||||
|
|
||||||
def __init__(self, *pargs):
|
|
||||||
super(Installer, self).__init__()
|
|
||||||
self.name = 'fas'
|
|
||||||
self.pargs = pargs
|
|
||||||
|
|
||||||
def install_args(self, group):
|
|
||||||
group.add_argument('--info-fas', choices=['yes', 'no'], default='no',
|
|
||||||
help='Configure FAS info')
|
|
||||||
group.add_argument('--info-fas-bind-username', action='store',
|
|
||||||
help='Username to use to retrieve FAS info')
|
|
||||||
group.add_argument('--info-fas-bind-password', action='store',
|
|
||||||
help='Password to use to retrieve FAS info')
|
|
||||||
|
|
||||||
def configure(self, opts, changes):
|
|
||||||
if opts['info_fas'] != 'yes':
|
|
||||||
return
|
|
||||||
|
|
||||||
# Add configuration data to database
|
|
||||||
po = PluginObject(*self.pargs)
|
|
||||||
po.name = 'fas'
|
|
||||||
po.wipe_data()
|
|
||||||
po.wipe_config_values()
|
|
||||||
|
|
||||||
config = dict()
|
|
||||||
if 'info_fas_bind_username' in opts:
|
|
||||||
config['Bind Username'] = opts['info_fas_bind_username']
|
|
||||||
if 'info_fas_bind_password' in opts:
|
|
||||||
config['Bind Password'] = opts['info_fas_bind_password']
|
|
||||||
po.save_plugin_config(config)
|
|
||||||
|
|
||||||
# Update global config to add login plugin
|
|
||||||
po.is_enabled = True
|
|
||||||
po.save_enabled_state()
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue