Ny integrasjon mellom SAP og UA
Sten Solli : USIT / ITI / APP
Universitetets Adgangskontrollsystem = Lenel OnGuard
Personer = Kortholdere
Alt ligger i en database
Det meste er tilgjenglig via WMI
Vi lager noe mellom OnGuard WMI / servicer og IntArk MQ / kildesystem API
MQ
UA
SAP
API GW
integrasjon@usit.uio.no
UA
# Pika is a python library for AMQP-0-9-1 (RabbitMQ)
import pika
# Set the connection parameters to connect to rabbit-server
credentials = pika.PlainCredentials(bah, kanin)
parameters = pika.ConnectionParameters(host='mq.uio.no', port=5671,virtual_host='/no/uio/integration',
ssl=True,ssl_options=dict(ssl_version=ssl.PROTOCOL_TLSv1), credentials=credentials)
connection = pika.BlockingConnection(parameters)
channel = connection.channel() #'/no/uio/ua/test')
channel.basic_qos(prefetch_count=1)
channel.basic_consume(callback, queue='q_sap_onguard')
# Start listening on queue
channel.start_consuming()
Begynner å lytte på riktig kø i MQ:
MQ
UA
En melding kommer:
Received b'{"sub":"https://api-gateway.uio.no/sws/v2/employees(11009182)",
"urn:ietf:params:event:SCIM:modify":{"attributes":["privateMobile"]},
"eventUris":["urn:ietf:params:event:SCIM:modify"],"iss":"sap",
"jti":"005056a9-4531-1ee9-88f3-818393c954bb","iat":1548752473,"aud":[]}'
def callback(ch, method, properties, body):
global lasturl, file, url
sapurl ="https://api-gateway.uio.no/sws/v2/employee"
time.sleep(body.count(b'.'))
body = body.decode("utf-8")
url = util.geturi(body)
if url == lasturl: pass
else:
if url.startswith(sapurl,0,len(sapurl)):
getsapdata(url)
ch.basic_ack(delivery_tag = method.delivery_tag)
lasturl = url
Er dette et attributt vi bryr oss om? Da behandler vi meldingen videre:
UA
SAP
API GW
#API bibliotek
import requests
def getsapdata(url):
assignments = {}
assurl = url + '/assignments'
# Henter data fra API
response = requests.get(url, headers=headers)
assign = requests.get(assurl, headers=headers)
util.loggline('nresponse.status_code = ' + str(response.status_code) )
# 200 = kontakt suksess (html)
if response.status_code == 200:
ansatt = getSAPAnsatt(response.text)
Henter data fra SAP API:
{'firstName': "Luke", 'lastName': "Skywalker", 'workEmail': "lukesk@usit.uio.no",
'norwegianIdentificationNumber': '1212120986', 'pid': '12121209862',
'employmentStatus': "active", 'personId': '19120400', 'hireDate': "2019-01-01",
'locationCode': None, 'passportIssuingCountry': None, 'passportNumber': None,
'kontakttelefon': "73782922"}
Får litt JSON til slutt:
### Henter Employeedata fra xml
def sapEmployed(prop):
temp = prop.find('d:firstName', ns)
firstName = setValue(temp)
loggline(firstName+"\n")
temp = prop.find('d:lastName', ns)
lastName = setValue(temp)
temp = prop.find('d:privateMobile', ns)
privateMobile = setValue(temp)
temp = prop.find('d:workEmail', ns)
workEmail = setValue(temp)
temp = prop.find('d:norwegianIdentificationNumber', ns)
norwegianIdentificationNumber = setValue(temp)
temp = prop.find('d:employmentStatus', ns)
employmentStatus = setValue(temp)
temp = prop.find('d:personId', ns)
personId = setValue(temp)
temp = prop.find('d:hireDate', ns)
hireDate = setValue(temp)
temp = prop.find('d:locationCode', ns)
locationCode = setValue(temp)
temp = prop.find('d:workPhone', ns)
workPhone = setValue(temp)
temp = prop.find('d:workMobile', ns)
workMobile = setValue(temp)
phone = setPhone(workMobile,privateMobile,workPhone)
temp=prop.find('d:passportIssuingCountry')
passportIssuingCountry=setValue(temp)
temp=prop.find('d:passportNumber')
passportNumber=setValue(temp)
### PID = pnummer i OnGuard
pid = str(norwegianIdentificationNumber)+"2"
ansatt = {'firstName': firstName,
'lastName' : lastName,
'workEmail': workEmail,
'norwegianIdentificationNumber': norwegianIdentificationNumber,
'pid': pid,
'employmentStatus' : employmentStatus,
'personId' : personId,
'hireDate': hireDate,
'locationCode': locationCode,
'passportIssuingCountry': passportIssuingCountry,
'passportNumber': passportNumber,
'kontakttelefon':phone
}
return ansatt
def getSAPAnsatt(xmldata):
ansatt = {}
### Som XML
root = ElementTree.fromstring(xmldata)
### Hente employee data fra SAP
for emp in root:
for prop in emp:
ansatt = util.sapEmployed(prop)
if ansatt is not None:
return ansatt
else:
return None
UA
OnGuard
onguarduser = wmihelper.getSAPCardholder(ansatt['pid'])
if onguarduser is not None:
updateSAPCardholder(ansatt,onguarduser)
else:
newSAPCardholder(ansatt)
Vi oppdaterer eller lager OnGuard kortholder:
def updateSAPCardholder(ansatt, onguarduser):
try:
if ansatt["firstName"] is not None: onguarduser = wmihelper.setWMIfnavn(onguarduser,ansatt)
if ansatt["lastName"] is not None: onguarduser = wmihelper.setWMIenavn(onguarduser,ansatt)
if ansatt["workEmail"] is not None: onguarduser = wmihelper.setWMIepost(onguarduser,ansatt)
if ansatt["personId"] is not None: onguarduser = wmihelper.setWMIansattnr(onguarduser,ansatt)
if ansatt["kontakttelefon"] is not None:
if str(ansatt["kontakttelefon"]).isdigit():onguarduser = wmihelper.setWMIphone(onguarduser,ansatt)
if ansatt["passportIssuingCountry"] is not None: instance.HOMEADR3 = ansatt["passportIssuingCountry"]
if ansatt["passportNumber"] is not None: instance.HOMEADR4 = ansatt["passportNumber"]
if ansatt["locationCode"] is not None: onguarduser = wmihelper.setWMIsted(onguarduser,ansatt)
if wmifrom is not None: onguarduser = wmihelper.setWMIfromdate(onguarduser,ansatt,wmifrom)
if wmitil is not None: onguarduser = wmihelper.setWMItodate(onguarduser,ansatt,wmitil)
# Assignement variables
if ansatt["locationId"] is not None:
onguarduser = wmihelper.setWMIlocation(onguarduser,ansatt)
## Kalle på funksjon som legger/fjerner tilganger basert på denne infoen
if ansatt["jobTitle"] is not None:
onguarduser = wmihelper.setWMItitle(onguarduser,ansatt)
## Kalle på funksjon som legger/fjerner tilganger basert på denne infoen
Her vil vi gjøre logikk for å behandle adgangsrettigheter automatisk
MQ
UA
Noen systemer vil vite når personer får nye adgangskort:
#Bruker igjen Pika biblioteket
import pika
lenel = wmi.WMI(moniker='//./root/OnGuard')
evtsrc = lenel.ExecNotificationQuery("SELECT * FROM __InstanceModificationEvent WHERE (TargetInstance ISA 'Lnl_Badge')" )
while True:
try:
badge = wmi.WMI(wmi=evtsrc.NextEvent(15000))
changedBadge = wmi.WMI(wmi=onguard.get_wmichange(badge) )
userID = str(changedBadge.PERSONID)
user = onguard.UserFromBadge(userID)
sted = onguard.getStedForUser(user)
rabbitmelding = {'timestamp':badge.TIME_CREATED, 'change' : 'Badge','sted':sted,'URL':'toCome'}
dictionaryToJson = json.dumps(rabbitmelding)
credentials = pika.PlainCredentials(humbug, kanin)
parameters = pika.ConnectionParameters(host='mq.uio.no', port=5671, virtual_host='/no/uio/ua/test',ssl=True,
credentials=credentials)
connection = pika.BlockingConnection(parameters)
channel = connection.channel()
channel.queue_declare(queue='q_onguard', durable=True)
result = channel.basic_publish(exchange='ex_uatest',
routing_key='badge.info',
body =dictionaryToJson,
mandatory=True
)
connection.close()
Vi skal: