/******************************************************************************\ * Copyright 2019 SAS Institute Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * Author: Vatslav Orlov * * Output: Authentication Token * * All code included in this section must be submitted in a * Viya 3.4 (or later) environment \******************************************************************************/ import requests #the only library actually required - to send requests import datetime #not required. Only here because of the optional logging I have included when testing ####################################################### # Function creates a logfile on the system in order # to have a reference to what was the app name, # tokens, and secret ####################################################### def createLogFile(): startTime = datetime.datetime.now() admRec = open("AdminRecords_" +str(startTime.year) + str(startTime.month) + str(startTime.day)+str(startTime.hour)+"_"+str(startTime.minute)+".txt", "x") return admRec ####################################################### # Function that prompts the user for the hostname # in the demo environment this is example.com ####################################################### def getHostName(): h_name_yn = input("The default hostname is: 'example.com'. Change? [Y/N]") if h_name_yn == "Y": hostname= str(input("Input hostname:")) else: hostname = "example.com" #admRec.write("The hostname has been set to: " +str(hostname)+ "\n") return hostname ####################################################### # Function that prompts the user to create an App name ####################################################### def getAppName(): appName = input("Provide application name:") #admRec.write("The App Name is: " +str(appName)+ " \n") return appName ####################################################### # Prompts the user for the secret # In this case the the person who is performing the # registration creates the secret to their linking ####################################################### def promptUserForSecret(): secret = input("Enter the secret phrase (you come up with one):") #admRec.write("The secret is: " +str(secret)+ " \n") return secret ####################################################### # Retrieve the Consul Token that is residing on the # primary Viya Node ####################################################### def getConsulToken(): with open('/opt/sas/viya/config/etc/SASSecurityCertificateFramework/tokens/consul/default/client.token', 'r') as file: data = file.read() if len(data) == 36: print("The consul Token is: [" + str(data)+"]") #admRec.write("The consul Token is: [" + str(data)+"] \n") return str(data) else: print("Consul Token returned is: [" + str(data) + "] however it is not 36 characters, program will now exit") ####################################################### # This function uses the Consul Token in order to # make a reqest to get a registartion OAuth token # for a given appName that the user provides ####################################################### def registrationOauthTokenReuqest(appName, consulToken): print("Attempting to get a registration Oauth token") url = "http://" +str(hostname)+ "/SASLogon/oauth/clients/consul?callback=false&serviceId="+ str(appName) headers = {"X-Consul-Token":str(consulToken)} r = requests.post(url, headers=headers, timeout=30) print(r) if r.status_code == 200: print(r.json()) print("-------ACCESS TOKEN: " + str(r.json()['access_token'])) #admRec.write("The access token is: " + str(r.json()['access_token']) + "\n") return r.json()['access_token'] else: print("Could not get registration oauth token") #################################################################### # This is where the actual registration happens # User provides the appName, a secret of their choice, # registration OAuth token and a validity (12 hrs by default) # # Admin would give python developer the name of the app and secret # after running this function #################################################################### def registerNewClient(appName, secret, authToken, validity=43199): print("Attempting to register") #admRec.write("Attempting to register \n") url = "https://" + str(hostname) + "/SASLogon/oauth/clients" headers = {"Content-Type":"application/json", "Authorization": "Bearer " + str(authToken)} data = {"client_id":str(appName), "client_secret":str(secret), "scope": "openid", "authorized_grant_types":"password", "access_token_validity":validity } r = requests.post(url,headers=headers, json=data, timeout=30, verify=False) print(r) if r.status_code == 201: print("Register success") #admRec.write("Register - success \n") print(r.json()) ####################################################### # MAIN # Space where all the functions are called ####################################################### try: #admRec = createLogFile() #create the log file appName = getAppName() # ask for app name hostname = getHostName() #ask for host name consulToken = getConsulToken() #get the consul token access_token = registrationOauthTokenReuqest(appName, consulToken) #get registration OAuth Token secret = promptUserForSecret() # prompt for secret registerNewClient(appName, secret, access_token, validity=43199) #register the app using the Oauth token #admRec.close() #close the log file print("Application Name: [" + str(appName) + "] Secret [" + str(secret) + "] - this is the info the python developer will need") except Exception as e: #admRec.close() #if encounter any errors, close the log file before exiting. print(str(e))