diff --git a/ConfigurationSystem/Client/Helpers/RESTConf.py b/ConfigurationSystem/Client/Helpers/RESTConf.py index fa064c5..02f661d 100644 --- a/ConfigurationSystem/Client/Helpers/RESTConf.py +++ b/ConfigurationSystem/Client/Helpers/RESTConf.py @@ -48,6 +48,9 @@ def key(): def setup(): return gConfig.getValue( "/DIRAC/Setup" ) +def getValue( path ): + return gConfig.getValue( path ) + def generateCAFile(): """ Generate a single CA file with all the PEMs diff --git a/RESTSystem/API/CS/CSHandler.py b/RESTSystem/API/CS/CSHandler.py new file mode 100644 index 0000000..223bad9 --- /dev/null +++ b/RESTSystem/API/CS/CSHandler.py @@ -0,0 +1,31 @@ +from tornado import web, gen +from RESTDIRAC.RESTSystem.Base.RESTHandler import RESTHandler +from RESTDIRAC.ConfigurationSystem.Client.Helpers import RESTConf + +class CSHandler( RESTHandler ): + + ROUTE = "/config/(Sections|Options|Value)" + + @web.asynchronous + def get( self, reqType ): + if reqType == "Sections": + return self.SectionsAction() + elif reqType == "Options": + return self.OptionsAction() + elif reqType == "Value": + return self.ValueAction() + + + @gen.engine + def ValueAction( self ): + args = self.request.arguments + try: + path = args[ 'ValuePath' ][0] + except KeyError: + self.send_error( 400 ) + return + condDict = {} + if 'allOwners' not in self.request.arguments: + condDict[ 'Owner' ] = self.getUserName() + result = RESTConf.getValue( path ) + self.finish( result ) diff --git a/RESTSystem/API/CS/__init__.py b/RESTSystem/API/CS/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/RESTSystem/API/oa2/TokenHandler.py b/RESTSystem/API/oa2/TokenHandler.py index a1a4bfd..b561fcb 100644 --- a/RESTSystem/API/oa2/TokenHandler.py +++ b/RESTSystem/API/oa2/TokenHandler.py @@ -75,12 +75,19 @@ def __getGroups( self, DN = False ): return WErr( 401, "No certificate received to issue a token" ) DN = credDict[ 'subject' ] if not credDict[ 'validDN' ]: - return WErr( 401, "Unknown DN %s" % DN ) + return WErr( 401, "Unknown DN %s" % DN ) result = Registry.getGroupsForDN( DN ) if not result[ 'OK' ]: return WErr( 500, result[ 'Message' ] ) return WOK( { 'groups' : result[ 'Value' ] } ) + def __getHostProperties ( self, group, DN ): + result = Registry.getPropertiesForEntity( group, dn = DN ) + if not result: + return WErr( 500, "Can't get the Property for the host" ) + return WOK( { 'groups' : result} ) + + def groupsAction( self ): result = self.__getGroups() if not result.ok: @@ -140,7 +147,11 @@ def __clientCredentialsRequest( self ): if not credDict[ 'validDN' ]: return WErr( 401, "Unknown DN %s" % DN ) #Check group - result = self.__getGroups( DN ) + if 'group' in credDict: + if credDict['group'] == 'hosts': + result = self.__getHostProperties( 'hosts', DN ) + else: + result = self.__getGroups( DN ) if not result.ok: return result groups = result.data[ 'groups' ] diff --git a/RESTSystem/Base/RESTHandler.py b/RESTSystem/Base/RESTHandler.py index 13e1cbe..da0c652 100644 --- a/RESTSystem/Base/RESTHandler.py +++ b/RESTSystem/Base/RESTHandler.py @@ -155,6 +155,8 @@ def prepare( self ): self.send_error( 401 ) else: data = result[ 'Value' ] + if data[ 'UserGroup' ] == 'TrustedHost': + data[ 'UserGroup' ] = 'hosts' self.__uData = { 'DN' : data[ 'UserDN' ], 'username' : data[ 'UserName' ], 'group' : data[ 'UserGroup' ], @@ -166,7 +168,6 @@ def prepare( self ): self.log.info( "Setting DISET for %s" % cs ) elif self.REQUIRE_ACCESS: raise WErr( 401, "No token provided" ) - self.end_prepare() diff --git a/RESTSystem/DB/OATokenDB.py b/RESTSystem/DB/OATokenDB.py index 062b4c9..fecef69 100755 --- a/RESTSystem/DB/OATokenDB.py +++ b/RESTSystem/DB/OATokenDB.py @@ -71,7 +71,7 @@ def __initializeDB( self ): 'Code' : 'CHAR(28)', 'Secret' : 'CHAR(28)', 'ClientID' : 'CHAR(28)', - 'UserName': 'VARCHAR(16) NOT NULL', + 'UserName': 'VARCHAR(32) NOT NULL', 'UserDN': 'VARCHAR(128) NOT NULL', 'UserGroup': 'VARCHAR(16) NOT NULL', 'UserSetup': 'VARCHAR(32) NOT NULL', @@ -292,7 +292,10 @@ def generateToken( self, userDN, userGroup, userSetup, scope = "", cid = False, if code: inData[ 'Code' ] = code - result = Registry.getUsernameForDN( userDN ) + if userGroup == 'TrustedHost': + result = Registry.getHostnameForDN( userDN ) + else: + result = Registry.getUsernameForDN( userDN ) if not result[ 'OK' ]: return result inData[ 'UserName' ] = result[ 'Value' ] diff --git a/RESTSystem/Test/CStest.py b/RESTSystem/Test/CStest.py new file mode 100644 index 0000000..cfcc0a4 --- /dev/null +++ b/RESTSystem/Test/CStest.py @@ -0,0 +1,43 @@ +""" +Test script that ask a token to the REST SERVER using a trusted host certificate. +Gets the job history using the token. +Gets the pilot commands using the token. +""" +import requests +import json + + +# The REST server url +REST_URL = 'https://0.0.0.0:9910' + +########################################### +# Get the access token first + +# GET request parameters +params = {'grant_type':'client_credentials', + 'group':'TrustedHost', + 'setup':'LHCb-Certification'} + +# The user certificate, password will be asked for to the user +# before request submission +#certificate = ('/home/cinzia/.globus/usercert.pem', +# '/home/cinzia/.globus/userkey.pem') + + +certificate = ('/home/cinzia/devRoot/etc/grid-security/hostcert.pem','/home/cinzia/devRoot/etc/grid-security/hostkey.pem') +# proxies=('/tmp/x509up_u1000','/tmp/x509up_u1000') +# result = requests.get(REST_URL+"/oauth2/token",params=params,cert=proxies, verify=False) + +result = requests.get(REST_URL+"/oauth2/token",params=params,cert=certificate,verify=False) + + +# the output is returned as a json encoded string, decode it here +resultDict = json.loads( result.text ) +access_token = resultDict['token'] + +JobHistory = requests.get(REST_URL+'/jobs/history',params={'access_token':access_token}, + verify=False) + +PilotCommands = requests.get(REST_URL+'/config/Value',params={'access_token':access_token,'ValuePath':'/Operations/LHCb-Certification/Pilot/Commands/BOINC'}, verify=False) + +########################################