Commit 830e567c authored by Albert's avatar Albert
Browse files

certificate and key matching fix, convert RSA to PKCS8

parent ca70a507
Pipeline #2667 failed with stage
import os
import tempfile
import subprocess
from myslicelib.api.cbas import Cbas, objects, fields, cbas_id
from myslicelib.util.sfa import hrn_to_urn, urn_to_hrn
import logging
logger = logging.getLogger(__name__)
......@@ -27,7 +31,7 @@ class MemberAuthority(Cbas):
elif entity in _ma:
return super(MemberAuthority, self).get_credential(urn, raw)
else:
return {'data':[], 'errors':[]}
return {'data': [], 'errors': []}
def set_sa(self, sa):
self.sa = sa
......@@ -52,12 +56,12 @@ class MemberAuthority(Cbas):
import traceback
traceback.print_exc()
self.logs.append({
'endpoint': self.endpoint.name,
'url': self.endpoint.url,
'protocol': self.endpoint.protocol,
'type': self.endpoint.type,
'exception': str(e)
})
'endpoint': self.endpoint.name,
'url': self.endpoint.url,
'protocol': self.endpoint.protocol,
'type': self.endpoint.type,
'exception': str(e)
})
return result
def _key(self, data):
......@@ -85,51 +89,54 @@ class MemberAuthority(Cbas):
k = self.get("key", urn)
users.append({
'id' : urn,
'shortname': u.get('MEMBER_USERNAME'),
'hrn': urn_to_hrn(u.get('MEMBER_URN'))[0],
'first_name': u.get('MEMBER_FIRSTNAME'),
'last_name': u.get('MEMBER_LASTNAME'),
'keys': k.get('data', []),
'certificate': u.get('MEMBER_CERTIFICATE'),
'email': u.get('MEMBER_EMAIL'),
'created': u.get('created'),
# 'updated': self._datetime(d['last_updated']),
'authority': authority,
'pi_authorities': pi_authorities,
'affiliation': u.get('_ONELAB_MEMBER_AFFILIATION', ''),
'city': u.get('_ONELAB_MEMBER_CITY', ''),
'country': u.get('_ONELAB_MEMBER_COUNTRY', ''),
# ],
#'projects': [
# hrn_to_urn(pi_auth, 'authority') for pi_auth in filter(lambda x: len(x.split('.')) > 2, u.get('reg-pi-authorities', []))
# ],
#'slices': [
# hrn_to_urn(sli, 'slice') for sli in u.get('reg-slices', [])
# ],
'id': urn,
'shortname': u.get('MEMBER_USERNAME'),
'hrn': urn_to_hrn(u.get('MEMBER_URN'))[0],
'first_name': u.get('MEMBER_FIRSTNAME'),
'last_name': u.get('MEMBER_LASTNAME'),
'keys': k.get('data', []),
'certificate': u.get('MEMBER_CERTIFICATE'),
'email': u.get('MEMBER_EMAIL'),
'created': u.get('created'),
# 'updated': self._datetime(d['last_updated']),
'authority': authority,
'pi_authorities': pi_authorities,
'affiliation': u.get('_ONELAB_MEMBER_AFFILIATION', ''),
'city': u.get('_ONELAB_MEMBER_CITY', ''),
'country': u.get('_ONELAB_MEMBER_COUNTRY', ''),
# ],
# 'projects': [
# hrn_to_urn(pi_auth, 'authority') for pi_auth in filter(lambda x: len(x.split('.')) > 2, u.get('reg-pi-authorities', []))
# ],
# 'slices': [
# hrn_to_urn(sli, 'slice') for sli in u.get('reg-slices', [])
# ],
})
return users
def _user_mappings(self, record_dict):
mapped_dict = {
#'MEMBER_URN': record_dict.get('id'),
# 'MEMBER_URN': record_dict.get('id'),
'MEMBER_USERNAME': record_dict.get('shortname'),
'MEMBER_EMAIL': record_dict.get('email'),
'MEMBER_FIRSTNAME': record_dict.get('first_name', ''),
'MEMBER_LASTNAME': record_dict.get('last_name', ''),
#'MEMBER_CERTIFICATE': record_dict.get('certificate',''),
# 'MEMBER_CERTIFICATE': record_dict.get('certificate',''),
'_ONELAB_MEMBER_AFFILIATION': record_dict.get('affiliation', ''),
'_ONELAB_MEMBER_CITY': record_dict.get('city', ''),
'_ONELAB_MEMBER_COUNTRY': record_dict.get('country', ''),
#'type': 'member',
#'keys' : record_dict.get('keys', '')
# 'type': 'member',
# 'keys' : record_dict.get('keys', '')
'KEY_PUBLIC': self.convert_pkcs8(next(iter(record_dict.get('keys', []) or []), None))
}
# filter key have empty value
mapped_dict = {k: v for k, v in mapped_dict.items() if v}
return mapped_dict
def _key_mappings(self, record_dict):
mapped_dict = {
'KEY_PUBLIC': next(iter(record_dict.get('keys', []) or []), None),
'KEY_TYPE': "rsa-ssh",
......@@ -147,8 +154,9 @@ class MemberAuthority(Cbas):
else:
cbas_entity = entity
mapped_dict = getattr(self, '_'+entity+'_mappings')(record_dict)
create_result = self._proxy.create(cbas_entity, [self.user_credential], {'fields':mapped_dict})
mapped_dict = getattr(self, '_' + entity + '_mappings')(record_dict)
create_result = self._proxy.create(cbas_entity, [self.user_credential], {'fields': mapped_dict})
self.save_key(urn, record_dict)
if 'code' not in create_result or create_result['code'] != 0:
if 'output' in create_result:
......@@ -162,13 +170,13 @@ class MemberAuthority(Cbas):
import traceback
traceback.print_exc()
self.logs.append({
'endpoint': self.endpoint.name,
'url': self.endpoint.url,
'protocol': self.endpoint.protocol,
'type': self.endpoint.type,
'exception': str(e)
})
return {'data':result,'errors':self.logs}
'endpoint': self.endpoint.name,
'url': self.endpoint.url,
'protocol': self.endpoint.protocol,
'type': self.endpoint.type,
'exception': str(e)
})
return {'data': result, 'errors': self.logs}
def save_key(self, urn, record_dict):
"""
......@@ -177,16 +185,17 @@ class MemberAuthority(Cbas):
try:
self.delete_keys(record_dict.get('id'))
if record_dict.get("keys") is not None:
mapped_dict = getattr(self, '_key'+'_mappings')(record_dict)
create_key_result = self._proxy.create("KEY", [self.user_credential], {'fields':mapped_dict})
mapped_dict = getattr(self, '_key' + '_mappings')(record_dict)
create_key_result = self._proxy.create("KEY", [self.user_credential], {'fields': mapped_dict})
# DUPLICATE ERROR => update KEY
if 'code' in create_key_result and create_key_result['code'] == 5:
k = self.get("key", urn, raw=True)
key_id = next (iter (k.keys()))
key_id = next(iter(k.keys()))
# UPDATE method do not support these fields
del mapped_dict["KEY_TYPE"]
del mapped_dict["KEY_MEMBER"]
update_key_result = self._proxy.update("KEY", key_id, [self.user_credential], {'fields':mapped_dict})
update_key_result = self._proxy.update("KEY", key_id, [self.user_credential],
{'fields': mapped_dict})
return True
except Exception as e:
......@@ -229,14 +238,15 @@ class MemberAuthority(Cbas):
else:
cbas_entity = entity
mapped_dict = getattr(self, '_'+entity+'_mappings')(record_dict)
mapped_dict = getattr(self, '_' + entity + '_mappings')(record_dict)
# UPDATE method do not support these fields
del mapped_dict["MEMBER_USERNAME"]
current = self.get(entity, urn)['data'][0]
self.update_sa(urn, 'slice', current, record_dict)
self.update_sa(urn, 'project', current, record_dict)
update_result = self._proxy.update(cbas_entity, urn, [self.user_credential], {'fields':mapped_dict})
update_result = self._proxy.update(cbas_entity, urn, [self.user_credential], {'fields': mapped_dict})
self.save_key(urn, record_dict)
res = self.get(entity, urn)
result = res['data']
......@@ -245,14 +255,14 @@ class MemberAuthority(Cbas):
import traceback
traceback.print_exc()
self.logs.append({
'endpoint': self.endpoint.name,
'url': self.endpoint.url,
'protocol': self.endpoint.protocol,
'type': self.endpoint.type,
'exception': str(e)
})
return {'data':result,'errors':self.logs}
'endpoint': self.endpoint.name,
'url': self.endpoint.url,
'protocol': self.endpoint.protocol,
'type': self.endpoint.type,
'exception': str(e)
})
return {'data': result, 'errors': self.logs}
def delete_keys(self, urn):
"""
......@@ -270,6 +280,28 @@ class MemberAuthority(Cbas):
return False
def convert_pkcs8(self, key):
try:
# Write the key in a temporary file
tempf, fpath = tempfile.mkstemp()
os.write(tempf, bytes(key, 'utf-8'))
os.close(tempf)
# Convert to PKCS8 (---BEGIN PUBLIC KEY---)
command = "ssh-keygen -e -m pkcs8 -f".split(' ')
command.append(fpath)
data = subprocess.run(command, stdout=subprocess.PIPE)
# Remove temporary file
os.remove(fpath)
except Exception as e:
logger.debug(e)
return
else:
return data.stdout.decode("utf-8")
class MaError(Exception):
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment