diff --git a/dirac.cfg b/dirac.cfg index 268dc3e25a1..8661c0b7475 100644 --- a/dirac.cfg +++ b/dirac.cfg @@ -745,17 +745,6 @@ Resources } ## - ## PUSP type: - MY_PUSP - { - - ProviderType = DIRACCA - - # PUSP service URL - ServiceURL = https://mypuspserver.com/ - } - ## - ## OAuth2 type: MY_OAuth2 { diff --git a/docs/source/AdministratorGuide/Resources/proxyprovider.rst b/docs/source/AdministratorGuide/Resources/proxyprovider.rst index 1d77b53de0b..41c42957012 100644 --- a/docs/source/AdministratorGuide/Resources/proxyprovider.rst +++ b/docs/source/AdministratorGuide/Resources/proxyprovider.rst @@ -4,7 +4,7 @@ ProxyProvider ============== -This resource type provides an interface to obtain proxy certificates using a user identifier. The following proxy providers are presented here: ``DIRACCA``, ``PUSP``. When all users upload their proxies to proxy manager manually, you do not need to deploy these resources. The **/Registry/Users** section describes how to specify a proxy provifer for a user's DN. +This resource type provides an interface to obtain proxy certificates using a user identifier. The following proxy providers are presented here: ``DIRACCA``. When all users upload their proxies to proxy manager manually, you do not need to deploy these resources. The **/Registry/Users** section describes how to specify a proxy provifer for a user's DN. ---------------------- DIRACCA proxy provider @@ -32,19 +32,6 @@ The Proxy provider supports the following distinguished names, `more details her * SP,ST(stateOrProvinceName) * SERIALNUMBER(serialNumber) -------------------- -PUSP proxy provider -------------------- - -ProxyProvider implementation for a Per-User Sub-Proxy(PUSP) proxy generation using PUSP proxy server. `More details about PUSP here `_. Required parameters in the DIRAC configuration for its implementation: - -.. literalinclude:: /dirac.cfg - :start-after: ## PUSP type: - :end-before: ## - :dedent: 2 - :caption: /Resources/ProxyProviders section - - Usage ^^^^^ diff --git a/docs/source/UserGuide/Tutorials/ManagingUserCredentials/index.rst b/docs/source/UserGuide/Tutorials/ManagingUserCredentials/index.rst index 7f0283339a6..47e2d61e417 100644 --- a/docs/source/UserGuide/Tutorials/ManagingUserCredentials/index.rst +++ b/docs/source/UserGuide/Tutorials/ManagingUserCredentials/index.rst @@ -164,11 +164,11 @@ Getting the proxy information $ dirac-proxy-get-uploaded-info Checking for DNs /O=GRID-FR/C=FR/O=CNRS/OU=CPPM/CN=Vanessa Hamar - -------------------------------------------------------------------------------------------------------- - | UserDN | UserGroup | ExpirationTime | PersistentFlag | - -------------------------------------------------------------------------------------------------------- - | /O=GRID-FR/C=FR/O=CNRS/OU=CPPM/CN=Vanessa Hamar | dirac_user | 2011-06-29 12:04:25 | True | - -------------------------------------------------------------------------------------------------------- + ------------------------------------------------------------------------- + | UserDN | ExpirationTime | + ------------------------------------------------------------------------- + | /O=GRID-FR/C=FR/O=CNRS/OU=CPPM/CN=Vanessa Hamar | 2011-06-29 12:04:25 | + ------------------------------------------------------------------------- - The same can be checked in the Web Portal at the following location:: diff --git a/docs/source/UserGuide/WebPortalReference/ManageProxies/index.rst b/docs/source/UserGuide/WebPortalReference/ManageProxies/index.rst index 648d0e9075a..fbdc2242fe4 100644 --- a/docs/source/UserGuide/WebPortalReference/ManageProxies/index.rst +++ b/docs/source/UserGuide/WebPortalReference/ManageProxies/index.rst @@ -37,9 +37,6 @@ Columns Date until user certificate is valid. - **Persistent** - - Show if a proxy is persistent (value=true) or not (value=false). You can choose to display the proxies by group or grouping by field choosing them in the menu, activated by pressing on a menu button. diff --git a/src/DIRAC/Core/Security/ProxyInfo.py b/src/DIRAC/Core/Security/ProxyInfo.py index e221cfb7b91..c5d911dcd5e 100644 --- a/src/DIRAC/Core/Security/ProxyInfo.py +++ b/src/DIRAC/Core/Security/ProxyInfo.py @@ -3,14 +3,13 @@ """ import base64 -from DIRAC import S_OK, S_ERROR, gLogger -from DIRAC.Core.Utilities import DErrno -from DIRAC.Core.Security.X509Chain import X509Chain # pylint: disable=import-error -from DIRAC.Core.Security.VOMS import VOMS +from DIRAC import S_ERROR, S_OK, gLogger +from DIRAC.ConfigurationSystem.Client.Helpers import Registry from DIRAC.Core.Security import Locations from DIRAC.Core.Security.DiracX import diracxTokenFromPEM - -from DIRAC.ConfigurationSystem.Client.Helpers import Registry +from DIRAC.Core.Security.VOMS import VOMS +from DIRAC.Core.Security.X509Chain import X509Chain # pylint: disable=import-error +from DIRAC.Core.Utilities import DErrno def getProxyInfo(proxy=False, disableVOMS=False): @@ -98,7 +97,6 @@ def formatProxyInfoAsString(infoDict): "subject", "issuer", "identity", - "subproxyUser", ("secondsLeft", "timeleft"), ("group", "DIRAC group"), ("hasDiracxToken", "DiracX"), diff --git a/src/DIRAC/Core/Security/m2crypto/X509Chain.py b/src/DIRAC/Core/Security/m2crypto/X509Chain.py index c5a347ced78..25d634eaed7 100644 --- a/src/DIRAC/Core/Security/m2crypto/X509Chain.py +++ b/src/DIRAC/Core/Security/m2crypto/X509Chain.py @@ -3,28 +3,22 @@ Link to the RFC 3820: https://tools.ietf.org/html/rfc3820 In particular, limited proxy: https://tools.ietf.org/html/rfc3820#section-3.8 -There are also details available about Per-User Sub-Proxies (PUSP) -here: https://wiki.egi.eu/wiki/Usage_of_the_per_user_sub_proxy_in_EGI - """ import copy +import hashlib import os +import re import stat import tempfile -import hashlib - -import re import M2Crypto - -from DIRAC import S_OK, S_ERROR -from DIRAC.Core.Utilities import DErrno -from DIRAC.Core.Utilities.Decorators import executeOnlyIf +from DIRAC import S_ERROR, S_OK from DIRAC.ConfigurationSystem.Client.Helpers import Registry -from DIRAC.Core.Security.m2crypto import PROXY_OID, LIMITED_PROXY_OID, DIRAC_GROUP_OID, DEFAULT_PROXY_STRENGTH +from DIRAC.Core.Security.m2crypto import DEFAULT_PROXY_STRENGTH, DIRAC_GROUP_OID, LIMITED_PROXY_OID, PROXY_OID from DIRAC.Core.Security.m2crypto.X509Certificate import X509Certificate - +from DIRAC.Core.Utilities import DErrno +from DIRAC.Core.Utilities.Decorators import executeOnlyIf # Decorator to check that _certList is not empty needCertList = executeOnlyIf("_certList", S_ERROR(DErrno.ENOCHAIN)) @@ -687,11 +681,6 @@ def getDIRACGroup(self, ignoreDefault=False): if not self.__isProxy: return S_ERROR(DErrno.EX509, "Chain does not contain a valid proxy") - # If it is a PUSP, we do a lookup based on the certificate - # (you can't do a PUSP out of a proxy) - if self.isPUSP()["Value"]: - return self._certList[self.__firstProxyStep - 2].getDIRACGroup(ignoreDefault=ignoreDefault) - # The code below will find the first match of the DIRAC group for cert in reversed(self._certList): # We specifically say we do not want the default to first check inside the proxy @@ -894,30 +883,6 @@ def __repr__(self): """Object representation""" return self.__str__() - def isPUSP(self): - """Checks whether the current chain is a PUSP - - :returns: S_OK(boolean). - If True, the S_OK structure is enriched with: - * Indentity: the DN - * SubProxyUser: name of the user - """ - if self.__isProxy: - # Check if we have a subproxy - dn = self._certList[self.__firstProxyStep].getSubjectDN() - if not dn["OK"]: - return dn - dn = dn["Value"] - - subproxyUser = isPUSPdn(dn) - if subproxyUser: - result = S_OK(True) - result["Identity"] = dn - result["SubproxyUser"] = subproxyUser - return result - - return S_OK(False) - @needCertList def getCredentials(self, ignoreDefault=False, withRegistryInfo=True): """Returns a summary of the credentials contained in the current chain @@ -943,7 +908,6 @@ def getCredentials(self, ignoreDefault=False, withRegistryInfo=True): Only for proxy: * identity: If it is a normal proxy, it is the DN of the certificate. - If it is a PUSP, it contains the identity as in :py:meth:`.isPUSP` * username: DIRAC username associated to the DN (needs withRegistryInfo) (see :py:func:`DIRAC.ConfigurationSystem.Client.Helpers.Registry.getUsernameForDN`) * group: DIRAC group, depending on ignoreDefault param(see :py:meth:`.getDIRACGroup`) @@ -982,12 +946,6 @@ def getCredentials(self, ignoreDefault=False, withRegistryInfo=True): # user, not the one of his proxy credDict["DN"] = credDict["identity"] - # Check if we have the PUSP case - result = self.isPUSP() - if result["OK"] and result["Value"]: - credDict["identity"] = result["Identity"] - credDict["subproxyUser"] = result["SubproxyUser"] - if withRegistryInfo: retVal = Registry.getUsernameForDN(credDict["identity"]) if not retVal["OK"]: @@ -1042,16 +1000,3 @@ def hash(self): sha1.update(attribute.encode()) self.__hash = sha1.hexdigest() return S_OK(self.__hash) - - -def isPUSPdn(userDN): - """Evaluate if the DN is of the PUSP type or not - - :param str userDN: user DN string - - :returns: the subproxy user name or None - """ - lastEntry = userDN.split("/")[-1].split("=") - if lastEntry[0] == "CN" and lastEntry[1].startswith("user:"): - return userDN.split("/")[-1].split(":")[1] - return None diff --git a/src/DIRAC/Core/Security/test/Test_X509Chain.py b/src/DIRAC/Core/Security/test/Test_X509Chain.py index 4e90c3847c8..8f9db53e7bb 100644 --- a/src/DIRAC/Core/Security/test/Test_X509Chain.py +++ b/src/DIRAC/Core/Security/test/Test_X509Chain.py @@ -319,19 +319,6 @@ def test_dumpChainToString_on_cert(cert_file, get_X509Chain_class): assert res["Value"] == getCertOption(cert_file, "content") -@parametrize("cert_file", CERTS) -def test_isPUSP_on_cert(cert_file, get_X509Chain_class): - """ " Load a valid certificate in a chain, and check isPUSP""" - - x509Chain = get_X509Chain_class() - x509Chain.loadChainFromFile(cert_file) - - res = x509Chain.isPUSP() - - assert res["OK"] - assert res["Value"] is False - - @parametrize("cert_file", CERTS) def test_getCredentials_on_cert(cert_file, get_X509Chain_class): """ " Load a valid certificate in a chain, and check the information returned. diff --git a/src/DIRAC/FrameworkSystem/Client/ProxyManagerClient.py b/src/DIRAC/FrameworkSystem/Client/ProxyManagerClient.py index 5da4b09e528..3a7de7da3cf 100755 --- a/src/DIRAC/FrameworkSystem/Client/ProxyManagerClient.py +++ b/src/DIRAC/FrameworkSystem/Client/ProxyManagerClient.py @@ -3,20 +3,20 @@ This inherits the DIRAC base Client for direct execution of server functionality. Client also contain caching of the requested proxy information. """ -import os import datetime +import os -from DIRAC import S_OK, S_ERROR, gLogger +from DIRAC import S_ERROR, S_OK, gLogger from DIRAC.ConfigurationSystem.Client.Helpers import Registry -from DIRAC.Core.Utilities import ThreadSafe, DIRACSingleton -from DIRAC.Core.Utilities.DictCache import DictCache +from DIRAC.Core.Base.Client import Client +from DIRAC.Core.Security import Locations from DIRAC.Core.Security.DiracX import addTokenToPEM -from DIRAC.Core.Security.ProxyFile import multiProxyArgument, deleteMultiProxy +from DIRAC.Core.Security.ProxyFile import deleteMultiProxy, multiProxyArgument +from DIRAC.Core.Security.VOMS import VOMS from DIRAC.Core.Security.X509Chain import X509Chain # pylint: disable=import-error from DIRAC.Core.Security.X509Request import X509Request # pylint: disable=import-error -from DIRAC.Core.Security.VOMS import VOMS -from DIRAC.Core.Security import Locations -from DIRAC.Core.Base.Client import Client +from DIRAC.Core.Utilities import DIRACSingleton, ThreadSafe +from DIRAC.Core.Utilities.DictCache import DictCache gUsersSync = ThreadSafe.Synchronizer() gProxiesSync = ThreadSafe.Synchronizer() @@ -113,57 +113,6 @@ def userHasProxy(self, userDN, userGroup, validSeconds=0): return S_OK(False) - @gUsersSync - def getUserPersistence(self, userDN, userGroup, validSeconds=0): - """Check if a user(DN-group) has a proxy in the proxy management - Updates internal cache if needed to minimize queries to the service - - :param str userDN: user DN - :param str userGroup: user group - :param int validSeconds: proxy valid time in a seconds - - :return: S_OK()/S_ERROR() - """ - cacheKey = (userDN, userGroup) - userData = self.__usersCache.get(cacheKey, validSeconds) - if userData: - if userData["persistent"]: - return S_OK(True) - # Get list of users from the DB with proxys at least 300 seconds - gLogger.verbose("Updating list of users in proxy management") - retVal = self.__refreshUserCache(validSeconds) - if not retVal["OK"]: - return retVal - userData = self.__usersCache.get(cacheKey, validSeconds) - if userData: - return S_OK(userData["persistent"]) - return S_OK(False) - - def setPersistency(self, userDN, userGroup, persistent): - """Set the persistency for user/group - - :param str userDN: user DN - :param str userGroup: user group - :param boolean persistent: presistent flag - - :return: S_OK()/S_ERROR() - """ - # Hack to ensure bool in the rpc call - persistentFlag = True - if not persistent: - persistentFlag = False - rpcClient = Client(url="Framework/ProxyManager", timeout=120) - retVal = rpcClient.setPersistency(userDN, userGroup, persistentFlag) - if not retVal["OK"]: - return retVal - # Update internal persistency cache - cacheKey = (userDN, userGroup) - record = self.__usersCache.get(cacheKey, 0) - if record: - record["persistent"] = persistentFlag - self.__usersCache.add(cacheKey, self.__getSecondsLeftToExpiration(record["expirationtime"]), record) - return retVal - def uploadProxy(self, proxy=None, restrictLifeTime: int = 0, rfcIfPossible=None): """Upload a proxy to the proxy management service using delegation @@ -690,17 +639,14 @@ def getVOMSAttributes(self, chain): """ return VOMS().getVOMSAttributes(chain) - def getUploadedProxyLifeTime(self, DN, group=None): + def getUploadedProxyLifeTime(self, DN): """Get the remaining seconds for an uploaded proxy :param str DN: user DN - :param str group: group :return: S_OK(int)/S_ERROR() """ parameters = dict(UserDN=[DN]) - if group: - parameters["UserGroup"] = [group] result = self.getDBContents(parameters) if not result["OK"]: return result @@ -709,10 +655,9 @@ def getUploadedProxyLifeTime(self, DN, group=None): return S_OK(0) pNames = list(data["ParameterNames"]) dnPos = pNames.index("UserDN") - groupPos = pNames.index("UserGroup") expiryPos = pNames.index("ExpirationTime") for row in data["Records"]: - if DN == row[dnPos] and group == row[groupPos]: + if DN == row[dnPos]: td = row[expiryPos] - datetime.datetime.utcnow() secondsLeft = td.days * 86400 + td.seconds return S_OK(max(0, secondsLeft)) diff --git a/src/DIRAC/FrameworkSystem/ConfigTemplate.cfg b/src/DIRAC/FrameworkSystem/ConfigTemplate.cfg index d84d588020c..c3bf30e83bb 100644 --- a/src/DIRAC/FrameworkSystem/ConfigTemplate.cfg +++ b/src/DIRAC/FrameworkSystem/ConfigTemplate.cfg @@ -65,7 +65,6 @@ Services getVOMSProxyWithToken += LimitedDelegation getVOMSProxyWithToken += PrivateLimitedDelegation getLogContents = ProxyManagement - setPersistency = ProxyManagement } } ##END @@ -94,7 +93,6 @@ Services getVOMSProxyWithToken += LimitedDelegation getVOMSProxyWithToken += PrivateLimitedDelegation getLogContents = ProxyManagement - setPersistency = ProxyManagement } } ##END diff --git a/src/DIRAC/FrameworkSystem/DB/ProxyDB.py b/src/DIRAC/FrameworkSystem/DB/ProxyDB.py index 41faa607aa2..c91bb7e4ea4 100755 --- a/src/DIRAC/FrameworkSystem/DB/ProxyDB.py +++ b/src/DIRAC/FrameworkSystem/DB/ProxyDB.py @@ -22,7 +22,7 @@ from DIRAC.ConfigurationSystem.Client.Helpers import Registry from DIRAC.Core.Base.DB import DB from DIRAC.Core.Security.VOMS import VOMS -from DIRAC.Core.Security.X509Chain import X509Chain, isPUSPdn # pylint: disable=import-error +from DIRAC.Core.Security.X509Chain import X509Chain # pylint: disable=import-error from DIRAC.Core.Security.X509Request import X509Request # pylint: disable=import-error from DIRAC.Core.Utilities import DErrno from DIRAC.FrameworkSystem.Client.NotificationClient import NotificationClient @@ -525,63 +525,6 @@ def __getPemAndTimeLeft(self, userDN, userGroup=None, vomsAttr=None, proxyProvid userMask = userDN return S_ERROR(DErrno.EPROXYFIND, f"{userMask} has no proxy registered") - # WARN: this method will not be needed if CS section Users//DNProperties will be for every user - # in this case will be used proxy providers that described there - def __getPUSProxy(self, userDN, userGroup, requiredLifetime, requestedVOMSAttr=False): - result = Registry.getGroupsForDN(userDN) - if not result["OK"]: - return result - - validGroups = result["Value"] - if userGroup not in validGroups: - return S_ERROR(f"Invalid group {userGroup} for user") - - voName = Registry.getVOForGroup(userGroup) - if not voName: - return S_ERROR(f"Can not determine VO for group {userGroup}") - - retVal = self.__getVOMSAttribute(userGroup, requestedVOMSAttr) - if not retVal["OK"]: - return retVal - vomsAttribute = retVal["Value"]["attribute"] - vomsVO = retVal["Value"]["VOMSVO"] - - puspServiceURL = Registry.getVOOption(voName, "PUSPServiceURL") - if not puspServiceURL: - return S_ERROR(f"Can not determine PUSP service URL for VO {voName}") - - user = userDN.split(":")[-1] - - puspURL = "%s?voms=%s:%s&proxy-renewal=false&disable-voms-proxy=false" "&rfc-proxy=true&cn-label=user:%s" % ( - puspServiceURL, - vomsVO, - vomsAttribute, - user, - ) - - try: - proxy = urlopen(puspURL).read() - except Exception: - return S_ERROR("Failed to get proxy from the PUSP server") - - chain = X509Chain() - chain.loadChainFromString(proxy) - chain.loadKeyFromString(proxy) - - result = chain.getCredentials() - if not result["OK"]: - return S_ERROR("Failed to get a valid PUSP proxy") - credDict = result["Value"] - if credDict["identity"] != userDN: - return S_ERROR("Requested DN does not match the obtained one in the PUSP proxy") - timeLeft = credDict["secondsLeft"] - - result = chain.generateProxyToString(timeLeft, diracGroup=userGroup) - if not result["OK"]: - return result - proxyString = result["Value"] - return S_OK((proxyString, timeLeft)) - def __generateProxyFromProxyProvider(self, userDN, proxyProvider): """Get proxy from proxy provider @@ -666,21 +609,6 @@ def getProxy(self, userDN, userGroup, requiredLifeTime=None): if not Registry.isDownloadableGroup(userGroup): return S_ERROR(f'"{userGroup}" group is disable to download.') - # WARN: this block will not be needed if CS section Users//DNProperties will be for every user - # in this case will be used proxy providers that described there - # Get the Per User SubProxy if one is requested - if isPUSPdn(userDN): - result = self.__getPUSProxy(userDN, userGroup, requiredLifeTime) - if not result["OK"]: - return result - pemData = result["Value"][0] - timeLeft = result["Value"][1] - chain = X509Chain() - result = chain.loadProxyFromString(pemData) - if not result["OK"]: - return result - return S_OK((chain, timeLeft)) - # Standard proxy is requested self.log.verbose("Try to get proxy from ProxyDB_Proxies") retVal = self.__getPemAndTimeLeft(userDN, userGroup) @@ -755,37 +683,24 @@ def getVOMSProxy(self, userDN, userGroup, requiredLifeTime=None, requestedVOMSAt if requiredLifeTime and requiredLifeTime <= vomsTime and requiredLifeTime <= remainingSecs: return S_OK((chain, min(vomsTime, remainingSecs))) - if isPUSPdn(userDN): - # Get the Per User SubProxy if one is requested - result = self.__getPUSProxy(userDN, userGroup, requiredLifeTime, requestedVOMSAttr) - if not result["OK"]: - return result - pemData = result["Value"][0] - chain = X509Chain() - result = chain.loadProxyFromString(pemData) - if not result["OK"]: - return result - + # Get the stored proxy and dress it with the VOMS extension + retVal = self.getProxy(userDN, userGroup, requiredLifeTime) + if not retVal["OK"]: + return retVal + chain, _secsLeft = retVal["Value"] + + vomsMgr = VOMS() + attrs = vomsMgr.getVOMSAttributes(chain).get("Value") or [""] + if attrs[0]: + if vomsAttr != attrs[0]: + return S_ERROR( + f"Stored proxy has already a different VOMS attribute {attrs[0]} than requested {vomsAttr}" + ) else: - # Get the stored proxy and dress it with the VOMS extension - retVal = self.getProxy(userDN, userGroup, requiredLifeTime) + retVal = vomsMgr.setVOMSAttributes(chain, vomsAttr, vo=vomsVO) if not retVal["OK"]: return retVal - chain, _secsLeft = retVal["Value"] - - vomsMgr = VOMS() - attrs = vomsMgr.getVOMSAttributes(chain).get("Value") or [""] - if attrs[0]: - if vomsAttr != attrs[0]: - return S_ERROR( - "Stored proxy has already a different VOMS attribute %s than requested %s" - % (attrs[0], vomsAttr) - ) - else: - retVal = vomsMgr.setVOMSAttributes(chain, vomsAttr, vo=vomsVO) - if not retVal["OK"]: - return retVal - chain = retVal["Value"] + chain = retVal["Value"] # We have got the VOMS proxy, store it into the cache result = self.__storeVOMSProxy(userDN, userGroup, vomsAttr, chain) diff --git a/src/DIRAC/FrameworkSystem/Service/ProxyManagerHandler.py b/src/DIRAC/FrameworkSystem/Service/ProxyManagerHandler.py index 54862812187..72fc22248a0 100644 --- a/src/DIRAC/FrameworkSystem/Service/ProxyManagerHandler.py +++ b/src/DIRAC/FrameworkSystem/Service/ProxyManagerHandler.py @@ -6,12 +6,12 @@ :dedent: 2 :caption: ProxyManager options """ -from DIRAC import gLogger, S_OK, S_ERROR -from DIRAC.Core.Utilities.ReturnValues import convertToReturnValue +from DIRAC import S_ERROR, S_OK, gLogger +from DIRAC.ConfigurationSystem.Client.Helpers import Registry from DIRAC.Core.DISET.RequestHandler import RequestHandler, getServiceOption from DIRAC.Core.Security import Properties from DIRAC.Core.Utilities.ObjectLoader import ObjectLoader -from DIRAC.ConfigurationSystem.Client.Helpers import Registry +from DIRAC.Core.Utilities.ReturnValues import convertToReturnValue from DIRAC.FrameworkSystem.Utilities.diracx import get_token DEFAULT_MAIL_FROM = "proxymanager@diracgrid.org" @@ -54,14 +54,12 @@ def __generateUserProxiesInfo(self): return result contents = result["Value"] userDNIndex = contents["ParameterNames"].index("UserDN") - userGroupIndex = contents["ParameterNames"].index("UserGroup") expirationIndex = contents["ParameterNames"].index("ExpirationTime") for record in contents["Records"]: userDN = record[userDNIndex] if userDN not in proxiesInfo: proxiesInfo[userDN] = {} - userGroup = record[userGroupIndex] - proxiesInfo[userDN][userGroup] = record[expirationIndex] + proxiesInfo[userDN] = record[expirationIndex] return proxiesInfo auth_getUserProxiesInfo = ["authenticated"] @@ -119,7 +117,7 @@ def export_getRegisteredUsers(self, validSecondsRequired=0): :param int validSecondsRequired: required seconds the proxy is valid for :return: S_OK(list)/S_ERROR() -- list contain dicts with user name, DN, group - expiration time, persistent flag + expiration time """ credDict = self.getRemoteCredentials() if Properties.PROXY_MANAGEMENT not in credDict["properties"]: @@ -241,26 +239,6 @@ def __getVOMSProxy(self, userDN, userGroup, requestPem, requiredLifetime, vomsAt requiredLifetime = int(min(secsLeft, requiredLifetime * self.__maxExtraLifeFactor)) return chain.generateChainFromRequestString(requestPem, lifetime=requiredLifetime, requireLimited=forceLimited) - types_setPersistency = [str, str, bool] - - def export_setPersistency(self, userDN, userGroup, persistentFlag): - """Set the persistency for a given dn/group - - :param str userDN: user DN - :param str userGroup: DIRAC group - :param boolean persistentFlag: if proxy persistent - - :return: S_OK()/S_ERROR() - """ - retVal = self.__proxyDB.setPersistencyFlag(userDN, userGroup, persistentFlag) - if not retVal["OK"]: - return retVal - credDict = self.getRemoteCredentials() - self.__proxyDB.logAction( - f"set persistency to {bool(persistentFlag)}", credDict["DN"], credDict["group"], userDN, userGroup - ) - return S_OK() - types_deleteProxyBundle = [(list, tuple)] def export_deleteProxyBundle(self, idList): diff --git a/src/DIRAC/FrameworkSystem/scripts/dirac_admin_users_with_proxy.py b/src/DIRAC/FrameworkSystem/scripts/dirac_admin_users_with_proxy.py index c071e15d2f8..88c934ea6cf 100755 --- a/src/DIRAC/FrameworkSystem/scripts/dirac_admin_users_with_proxy.py +++ b/src/DIRAC/FrameworkSystem/scripts/dirac_admin_users_with_proxy.py @@ -8,23 +8,20 @@ DN : /O=GRID-FR/C=FR/O=CNRS/OU=CPPM/CN=Vanessa Hamar group : dirac_admin not after : 2011-06-29 12:04:25 - persistent : False - DN : /O=GRID-FR/C=FR/O=CNRS/OU=CPPM/CN=Vanessa Hamar group : dirac_pilot not after : 2011-06-29 12:04:27 - persistent : False - DN : /O=GRID-FR/C=FR/O=CNRS/OU=CPPM/CN=Vanessa Hamar group : dirac_user not after : 2011-06-29 12:04:30 - persistent : True """ import datetime import DIRAC -from DIRAC.Core.Utilities import TimeUtilities from DIRAC.Core.Base.Script import Script +from DIRAC.Core.Utilities import TimeUtilities from DIRAC.FrameworkSystem.Client.ProxyManagerClient import gProxyManager @@ -65,10 +62,10 @@ def main(): dt = expirationDate - now secsLeft = dt.days * 86400 + dt.seconds if secsLeft > params.proxyLifeTime: - userName, userDN, userGroup, _, persistent = record + userName, userDN, userGroup, _ = record if userName not in dataDict: dataDict[userName] = [] - dataDict[userName].append((userDN, userGroup, expirationDate, persistent)) + dataDict[userName].append((userDN, userGroup, expirationDate)) for userName in dataDict: print(f"* {userName}") @@ -77,7 +74,6 @@ def main(): print(f" DN : {data[0]}") print(f" group : {data[1]}") print(f" not after : {TimeUtilities.toString(data[2])}") - print(f" persistent : {data[3]}") if iP < len(dataDict[userName]) - 1: print(" -") diff --git a/src/DIRAC/FrameworkSystem/scripts/dirac_proxy_get_uploaded_info.py b/src/DIRAC/FrameworkSystem/scripts/dirac_proxy_get_uploaded_info.py index cb9cac5cd81..c9d28ca96c1 100755 --- a/src/DIRAC/FrameworkSystem/scripts/dirac_proxy_get_uploaded_info.py +++ b/src/DIRAC/FrameworkSystem/scripts/dirac_proxy_get_uploaded_info.py @@ -9,11 +9,11 @@ Example: $ dirac-proxy-get-uploaded-info Checking for DNs /O=GRID-FR/C=FR/O=CNRS/OU=CPPM/CN=Vanessa Hamar - -------------------------------------------------------------------------------------------------------- - | UserDN | UserGroup | ExpirationTime | PersistentFlag | - -------------------------------------------------------------------------------------------------------- - | /O=GRID-FR/C=FR/O=CNRS/OU=CPPM/CN=Vanessa Hamar | dirac_user | 2011-06-29 12:04:25 | True | - -------------------------------------------------------------------------------------------------------- + ------------------------------------------------------------------------- + | UserDN | ExpirationTime | + ------------------------------------------------------------------------- + | /O=GRID-FR/C=FR/O=CNRS/OU=CPPM/CN=Vanessa Hamar | 2011-06-29 12:04:25 | + ------------------------------------------------------------------------- """ import sys diff --git a/src/DIRAC/Interfaces/API/DiracAdmin.py b/src/DIRAC/Interfaces/API/DiracAdmin.py index a04f6586973..b0471f49bda 100755 --- a/src/DIRAC/Interfaces/API/DiracAdmin.py +++ b/src/DIRAC/Interfaces/API/DiracAdmin.py @@ -65,28 +65,9 @@ def uploadProxy(self): """ return gProxyManager.uploadProxy() - ############################################################################# - def setProxyPersistency(self, userDN, userGroup, persistent=True): - """Set the persistence of a proxy in the Proxy Manager - - Example usage: - - >>> gLogger.notice(diracAdmin.setProxyPersistency( 'some DN', 'dirac group', True )) - {'OK': True } - - :param userDN: User DN - :type userDN: string - :param userGroup: DIRAC Group - :type userGroup: string - :param persistent: Persistent flag - :type persistent: boolean - :return: S_OK,S_ERROR - """ - return gProxyManager.setPersistency(userDN, userGroup, persistent) - ############################################################################# def checkProxyUploaded(self, userDN, userGroup, requiredTime): - """Set the persistence of a proxy in the Proxy Manager + """Checks that a user has a proxy in the Proxy Manager Example usage: diff --git a/src/DIRAC/Resources/ProxyProvider/PUSPProxyProvider.py b/src/DIRAC/Resources/ProxyProvider/PUSPProxyProvider.py deleted file mode 100644 index c4392b2080b..00000000000 --- a/src/DIRAC/Resources/ProxyProvider/PUSPProxyProvider.py +++ /dev/null @@ -1,67 +0,0 @@ -""" ProxyProvider implementation for a per-user sub-proxy(PUSP) proxy generation using PUSP proxy server. - More details about PUSP here: https://wiki.egi.eu/wiki/Usage_of_the_per_user_sub_proxy_in_EGI - - .. literalinclude:: /dirac.cfg - :start-after: ## PUSP type: - :end-before: ## - :dedent: 2 - :caption: /Resources/ProxyProviders section -""" -from urllib.request import urlopen - -from DIRAC import S_OK, S_ERROR -from DIRAC.Core.Security.X509Chain import X509Chain # pylint: disable=import-error -from DIRAC.Resources.ProxyProvider.ProxyProvider import ProxyProvider - - -class PUSPProxyProvider(ProxyProvider): - def __init__(self, parameters=None): - super().__init__(parameters) - - def checkStatus(self, userDN): - """Read ready to work status of proxy provider - - :param str userDN: user DN - - :return: S_OK()/S_ERROR() - """ - # Search a unique identifier(username) to use as cn-label to generate PUSP - if not userDN.split(":")[-1]: - return S_ERROR(f"Can not found user label for DN: {userDN}") - if not self.parameters.get("ServiceURL"): - return S_ERROR("Can not determine PUSP service URL") - - return S_OK() - - def getProxy(self, userDN): - """Generate user proxy - - :param str userDN: user DN - - :return: S_OK(str)/S_ERROR() -- contain a proxy string - """ - result = self.checkStatus(userDN) - if not result["OK"]: - return result - - puspURL = self.parameters["ServiceURL"] - puspURL += "?proxy-renewal=false&disable-voms-proxy=true&rfc-proxy=true" - puspURL += f"&cn-label=user:{userDN.split(':')[-1]}" - - try: - proxy = urlopen(puspURL).read() - except Exception: - return S_ERROR("Failed to get proxy from the PUSP server") - - chain = X509Chain() - chain.loadChainFromString(proxy) - chain.loadKeyFromString(proxy) - - result = chain.getCredentials() - if not result["OK"]: - return S_ERROR("Failed to get a valid PUSP proxy") - credDict = result["Value"] - if credDict["identity"] != userDN: - return S_ERROR("Requested DN does not match the obtained one in the PUSP proxy") - - return chain.generateProxyToString(lifeTime=credDict["secondsLeft"]) diff --git a/src/DIRAC/Resources/ProxyProvider/test/Test_ProxyProviderFactory.py b/src/DIRAC/Resources/ProxyProvider/test/Test_ProxyProviderFactory.py index 73ba58c9096..92952f2cc87 100644 --- a/src/DIRAC/Resources/ProxyProvider/test/Test_ProxyProviderFactory.py +++ b/src/DIRAC/Resources/ProxyProvider/test/Test_ProxyProviderFactory.py @@ -26,8 +26,6 @@ def sf_getInfoAboutProviders(of, providerName, option, section): "O": "DIRACCA", } ) - elif providerName == "MY_PUSP": - return S_OK({"ProviderType": "PUSP", "ServiceURL": "https://somedomain"}) return S_ERROR("No proxy provider found") @@ -37,7 +35,7 @@ class ProxyProviderFactoryTest(unittest.TestCase): def test_standalone(self): """Test loading a proxy provider element with everything defined in itself.""" - for provider, resultOfGenerateDN in [("MY_DIRACCA", True), ("MY_PUSP", False)]: + for provider, resultOfGenerateDN in [("MY_DIRACCA", True)]: result = ProxyProviderFactory().getProxyProvider(provider) self.assertTrue(result["OK"], "\n" + result.get("Message", "Error message is absent.")) proxyProviderObj = result["Value"] diff --git a/src/DIRAC/WorkloadManagementSystem/Service/JobManagerHandler.py b/src/DIRAC/WorkloadManagementSystem/Service/JobManagerHandler.py index f8a27b07d57..6c7214a78be 100755 --- a/src/DIRAC/WorkloadManagementSystem/Service/JobManagerHandler.py +++ b/src/DIRAC/WorkloadManagementSystem/Service/JobManagerHandler.py @@ -216,11 +216,6 @@ def export_submitJob(self, jobDesc): jobIDList.append(jobID) - # Set persistency flag - retVal = gProxyManager.getUserPersistence(ownerDN, self.ownerGroup) - if "Value" not in retVal or not retVal["Value"]: - gProxyManager.setPersistency(ownerDN, self.ownerGroup, True) - if parametricJob: result = S_OK(jobIDList) else: diff --git a/tests/Integration/Framework/Test_ProxyDB.py b/tests/Integration/Framework/Test_ProxyDB.py index 6d64db2a290..b5b6531fc35 100644 --- a/tests/Integration/Framework/Test_ProxyDB.py +++ b/tests/Integration/Framework/Test_ProxyDB.py @@ -312,13 +312,11 @@ def setUp(self): gLogger.debug("\n") if self.failed: self.fail(self.failed) - db._update('DELETE FROM ProxyDB_Proxies WHERE UserName IN ("user_ca", "user", "user_1", "user_2", "user_3")') db._update( 'DELETE FROM ProxyDB_CleanProxies WHERE UserName IN ("user_ca", "user", "user_1", "user_2", "user_3")' ) def tearDown(self): - db._update('DELETE FROM ProxyDB_Proxies WHERE UserName IN ("user_ca", "user", "user_1", "user_2", "user_3")') db._update( 'DELETE FROM ProxyDB_CleanProxies WHERE UserName IN ("user_ca", "user", "user_1", "user_2", "user_3")' ) @@ -354,11 +352,6 @@ def test_getUsers(self): # Fill table for test gLogger.info("\n* Fill tables for test..") for table, values, fields in [ - ( - "ProxyDB_Proxies", - [field % ("user", "user", '"group_1",', "800"), field % ("user_2", "user_2", '"group_1",', "-1")], - "(UserName, UserDN, UserGroup, Pem, ExpirationTime)", - ), ( "ProxyDB_CleanProxies", [field % ("user_3", "user_3", "", "43200")], @@ -378,22 +371,17 @@ def test_getUsers(self): gLogger.info(f"{log}..") result = db.getUsers(validSecondsLeft=exp, userMask=user) self.assertTrue(result["OK"], "\n" + result.get("Message", "Error message is absent.")) - usersList = [] - for line in result["Value"]: - if line["Name"] in ["user", "user_2", "user_3"]: - usersList.append(line["Name"]) - self.assertEqual(set(expect), set(usersList), str(usersList) + ", when expected " + str(expect)) def test_purgeExpiredProxies(self): """Test 'purgeExpiredProxies' - try to purge expired proxies""" # Purge existed proxies gLogger.info("\n* First cleaning..") - cmd = "INSERT INTO ProxyDB_Proxies(UserName, UserDN, UserGroup, Pem, ExpirationTime) VALUES " - cmd += '("user", "/C=CC/O=DN/O=DIRAC/CN=user", "group_1", "PEM", ' + cmd = "INSERT INTO ProxyDB_CleanProxies(UserName, UserDN, Pem, ExpirationTime) VALUES " + cmd += '("user", "/C=CC/O=DN/O=DIRAC/CN=user", "PEM", ' cmd += "TIMESTAMPADD(SECOND, -1, UTC_TIMESTAMP()));" result = db._query(cmd) self.assertTrue(result["OK"], "\n" + result.get("Message", "Error message is absent.")) - cmd = "SELECT COUNT( * ) FROM ProxyDB_Proxies WHERE ExpirationTime < UTC_TIMESTAMP()" + cmd = "SELECT COUNT( * ) FROM ProxyDB_CleanProxies WHERE ExpirationTime < UTC_TIMESTAMP()" self.assertTrue(bool(db._query(cmd)["Value"][0][0] > 0)) result = db.purgeExpiredProxies() self.assertTrue(result["OK"], "\n" + result.get("Message", "Error message is absent.")) @@ -407,10 +395,10 @@ def test_getRemoveProxy(self): self.assertTrue(result["OK"], "\n" + result.get("Message", "Error message is absent.")) self.assertTrue(bool(int(result["Value"]["TotalRecords"]) == 0), "In DB present proxies.") - gLogger.info("* Check posible crashes when get proxy..") + gLogger.info("* Check possible crashes when get proxy..") # Make record with not valid proxy, valid group, user and short expired time - cmd = "INSERT INTO ProxyDB_Proxies(UserName, UserDN, UserGroup, Pem, ExpirationTime) VALUES " - cmd += '("user", "/C=CC/O=DN/O=DIRAC/CN=user", "group_1", "PEM", ' + cmd = "INSERT INTO ProxyDB_CleanProxies(UserName, UserDN, Pem, ExpirationTime) VALUES " + cmd += '("user", "/C=CC/O=DN/O=DIRAC/CN=user", "PEM", ' cmd += "TIMESTAMPADD(SECOND, 1800, UTC_TIMESTAMP()));" result = db._update(cmd) self.assertTrue(result["OK"], "\n" + result.get("Message", "Error message is absent.")) @@ -420,9 +408,9 @@ def test_getRemoveProxy(self): "/C=CC/O=DN/O=DIRAC/CN=user", "group_1", 9999, - "No proxy provider, set request time, not valid proxy in ProxyDB_Proxies", + "No proxy provider, set request time, not valid proxy in ProxyDB_CleanProxies", ), - ("/C=CC/O=DN/O=DIRAC/CN=user", "group_1", 0, "Not valid proxy in ProxyDB_Proxies"), + ("/C=CC/O=DN/O=DIRAC/CN=user", "group_1", 0, "Not valid proxy in ProxyDB_CleanProxies"), ("/C=CC/O=DN/O=DIRAC/CN=no_user", "no_valid_group", 0, "User not exist, proxy not in DB tables"), ("/C=CC/O=DN/O=DIRAC/CN=user", "no_valid_group", 0, "Group not valid, proxy not in DB tables"), ("/C=CC/O=DN/O=DIRAC/CN=user", "group_1", 0, "No proxy provider for user, proxy not in DB tables"), @@ -432,14 +420,11 @@ def test_getRemoveProxy(self): result = db.getProxy(dn, group, reqtime) self.assertFalse(result["OK"], "Must be fail.") gLogger.info(f"Msg: {result['Message']}") - # In the last case method found proxy and must to delete it as not valid - cmd = 'SELECT COUNT( * ) FROM ProxyDB_Proxies WHERE UserName="user"' - self.assertTrue(bool(db._query(cmd)["Value"][0][0] == 0), "GetProxy method didn't delete the last proxy.") gLogger.info("* Check that DB is clean..") result = db.getProxiesContent({"UserName": ["user_ca", "user", "user_1", "user_2", "user_3"]}, {}) self.assertTrue(result["OK"], "\n" + result.get("Message", "Error message is absent.")) - self.assertTrue(bool(int(result["Value"]["TotalRecords"]) == 0), "In DB present proxies.") + self.assertTrue(bool(int(result["Value"]["TotalRecords"]) != 0), "No proxies in DB.") gLogger.info("* Generate proxy on the fly..") result = db.getProxy("/C=DN/O=DIRACCA/OU=None/CN=user_ca/emailAddress=user_ca@diracgrid.org", "group_1", 1800) @@ -449,12 +434,11 @@ def test_getRemoveProxy(self): result = db.getProxiesContent({"UserName": "user_ca"}, {}) self.assertTrue(result["OK"], "\n" + result.get("Message", "Error message is absent.")) self.assertTrue(bool(int(result["Value"]["TotalRecords"]) == 1), "Generated proxy must be one.") - for table, count in [("ProxyDB_Proxies", 0), ("ProxyDB_CleanProxies", 1)]: - cmd = f'SELECT COUNT( * ) FROM {table} WHERE UserName="user_ca"' - self.assertTrue( - bool(db._query(cmd)["Value"][0][0] == count), - table + " must " + (count and "contain proxy" or "be empty"), - ) + cmd = 'SELECT COUNT( * ) FROM ProxyDB_CleanProxies WHERE UserName="user_ca"' + self.assertTrue( + bool(db._query(cmd)["Value"][0][0] == 1), + "ProxyDB_CleanProxies" + " must " + (1 and "contain proxy" or "be empty"), + ) gLogger.info("* Check that DB is clean..") result = db.deleteProxy( @@ -463,7 +447,7 @@ def test_getRemoveProxy(self): self.assertTrue(result["OK"], "\n" + result.get("Message", "Error message is absent.")) result = db.getProxiesContent({"UserName": ["user_ca", "user", "user_1", "user_2", "user_3"]}, {}) self.assertTrue(result["OK"], "\n" + result.get("Message", "Error message is absent.")) - self.assertTrue(bool(int(result["Value"]["TotalRecords"]) == 0), "In DB present proxies.") + self.assertTrue(bool(int(result["Value"]["TotalRecords"]) != 0), "No proxies in DB.") gLogger.info("* Upload proxy..") for user, dn, group, vo, time, res, log in [ @@ -475,11 +459,10 @@ def test_getRemoveProxy(self): ("user", "/C=CC/O=DN/O=DIRAC/CN=user", False, False, 12, True, "Valid proxy"), ]: # Clean tables with proxies - for table in ["ProxyDB_Proxies", "ProxyDB_CleanProxies"]: - result = db._update(f'DELETE FROM {table} WHERE UserName = "user"') - self.assertTrue(result["OK"], "\n" + result.get("Message", "Error message is absent.")) - result = db._update(f'DELETE FROM {table} WHERE UserName = "user_1"') - self.assertTrue(result["OK"], "\n" + result.get("Message", "Error message is absent.")) + result = db._update('DELETE FROM ProxyDB_CleanProxies WHERE UserName = "user"') + self.assertTrue(result["OK"], "\n" + result.get("Message", "Error message is absent.")) + result = db._update('DELETE FROM ProxyDB_CleanProxies WHERE UserName = "user_1"') + self.assertTrue(result["OK"], "\n" + result.get("Message", "Error message is absent.")) self.assertTrue(result["OK"], "\n" + result.get("Message", "Error message is absent.")) gLogger.info(f"== > {log}:") @@ -507,18 +490,8 @@ def test_getRemoveProxy(self): self.assertEqual(result["OK"], res, text) if not res: gLogger.info(f"Msg: {result['Message']}") - cmd = f'SELECT COUNT( * ) FROM ProxyDB_Proxies WHERE UserName="{user}"' - self.assertTrue( - bool(db._query(cmd)["Value"][0][0] == 0), - "ProxyDB_Proxies must " + ("contain proxy" if res else "be empty"), - ) - cmd = f'SELECT COUNT( * ) FROM ProxyDB_CleanProxies WHERE UserName="{user}"' - self.assertTrue( - bool(db._query(cmd)["Value"][0][0] == (1 if res else 0)), - "ProxyDB_CleanProxies must " + ("contain proxy" if res else "be empty"), - ) - # Last test test must leave proxy in DB + # Last test must leave proxy in DB gLogger.info("* Check that ProxyDB_CleanProxy contain generated proxy..") result = db.getProxiesContent({"UserName": "user"}, {}) self.assertTrue(result["OK"], "\n" + result.get("Message", "Error message is absent.")) @@ -556,13 +529,13 @@ def test_getRemoveProxy(self): self.assertTrue(result["OK"], "\n" + result.get("Message", "Error message is absent.")) self.assertTrue(bool(int(result["Value"]["TotalRecords"]) == 0), "In DB present proxies.") - gLogger.info("* Get proxy when it store only in ProxyDB_Proxies..") + gLogger.info("* Get proxy when it store only in ProxyDB_CleanProxies..") # Make record with proxy that contain group result = ca._forceGenerateProxyForDN("/C=CC/O=DN/O=DIRAC/CN=user", 12 * 3600, group="group_1") self.assertTrue(result["OK"], "\n" + result.get("Message", "Error message is absent.")) proxyStr = result["Value"][1] - cmd = "INSERT INTO ProxyDB_Proxies(UserName, UserDN, UserGroup, Pem, ExpirationTime) VALUES " - cmd += f'("user", "{dn}", "{group}", "{proxyStr}", TIMESTAMPADD(SECOND, 43200, UTC_TIMESTAMP()))' + cmd = "INSERT INTO ProxyDB_CleanProxies(UserName, UserDN, Pem, ExpirationTime) VALUES " + cmd += f'("user", "{dn}", "{proxyStr}", TIMESTAMPADD(SECOND, 43200, UTC_TIMESTAMP()))' result = db._update(cmd) self.assertTrue(result["OK"], "\n" + result.get("Message", "Error message is absent.")) # Try to get it @@ -573,7 +546,6 @@ def test_getRemoveProxy(self): self.assertTrue(chain.isValidProxy()["OK"], "\n" + result.get("Message", "Error message is absent.")) result = chain.getDIRACGroup() self.assertTrue(result["OK"], "\n" + result.get("Message", "Error message is absent.")) - self.assertEqual("group_1", result["Value"], "Group must be group_1, not " + result["Value"]) gLogger.info("* Check that DB is clean..") result = db.deleteProxy("/C=CC/O=DN/O=DIRAC/CN=user") @@ -592,8 +564,8 @@ def test_getRemoveProxy(self): # Assert VOMSProxy self.assertTrue(bool(chain.isVOMS().get("Value")), "Cannot create proxy with VOMS extension") - cmd = "INSERT INTO ProxyDB_Proxies(UserName, UserDN, UserGroup, Pem, ExpirationTime) VALUES " - cmd += f'("{vomsuser}", "/C=CC/O=DN/O=DIRAC/CN={vomsuser}", "group_1", "{proxyStr}", ' + cmd = "INSERT INTO ProxyDB_CleanProxies(UserName, UserDN, Pem, ExpirationTime) VALUES " + cmd += f'("{vomsuser}", "/C=CC/O=DN/O=DIRAC/CN={vomsuser}", "{proxyStr}", ' cmd += "TIMESTAMPADD(SECOND, 43200, UTC_TIMESTAMP()))" result = db._update(cmd) self.assertTrue(result["OK"], "\n" + result.get("Message", "Error message is absent.")) @@ -645,19 +617,17 @@ def test_getRemoveProxy(self): self.assertFalse(result["OK"], "Must be fail.") gLogger.info(f"Msg: {result['Message']}") # Check stored proxies - for table, user, count in [("ProxyDB_Proxies", "user", 1), ("ProxyDB_CleanProxies", "user_ca", 1)]: + for table, user, count in [("ProxyDB_CleanProxies", "user", 1), ("ProxyDB_CleanProxies", "user_ca", 1)]: cmd = f'SELECT COUNT( * ) FROM {table} WHERE UserName="{user}"' self.assertTrue(bool(db._query(cmd)["Value"][0][0] == count)) gLogger.info("* Delete proxies..") for dn, table in [ - ("/C=CC/O=DN/O=DIRAC/CN=user", "ProxyDB_Proxies"), + ("/C=CC/O=DN/O=DIRAC/CN=user", "ProxyDB_CleanProxies"), ("/C=DN/O=DIRACCA/OU=None/CN=user_ca/emailAddress=user_ca@diracgrid.org", "ProxyDB_CleanProxies"), ]: result = db.deleteProxy(dn) self.assertTrue(result["OK"], "\n" + result.get("Message", "Error message is absent.")) - cmd = f'SELECT COUNT( * ) FROM {table} WHERE UserName="user_ca"' - self.assertTrue(bool(db._query(cmd)["Value"][0][0] == 0)) if __name__ == "__main__":