Skip to content

Commit 9bc3d76

Browse files
authored
Merge pull request #5899 from TaykYoku/8.0_fixOAuth-2
[8.0][OAuth 2] dirac-login (AS) added VOMS extension
2 parents a24dae3 + ecd89a4 commit 9bc3d76

File tree

2 files changed

+41
-14
lines changed

2 files changed

+41
-14
lines changed

src/DIRAC/FrameworkSystem/private/authorization/AuthServer.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
wrapIDAsDN,
2222
getDNForUsername,
2323
getIdPForGroup,
24+
getGroupOption,
2425
)
2526
from DIRAC.FrameworkSystem.Client.ProxyManagerClient import ProxyManagerClient
2627
from DIRAC.FrameworkSystem.Client.TokenManagerClient import TokenManagerClient
@@ -156,10 +157,15 @@ def generateProxyOrToken(
156157
# Try every DN to generate a proxy
157158
for dn in userDNs:
158159
sLog.debug("Try to get proxy for %s" % dn)
160+
params = {}
159161
if lifetime:
160-
result = self.proxyCli.downloadProxy(dn, group, requiredTimeLeft=int(lifetime))
162+
params["requiredTimeLeft"] = int(lifetime)
163+
# if the configuration describes adding a VOMS extension, we will do so
164+
if getGroupOption(group, "AutoAddVOMS", False):
165+
result = self.proxyCli.downloadVOMSProxy(dn, group, **params)
161166
else:
162-
result = self.proxyCli.downloadProxy(dn, group)
167+
# otherwise we will return the usual proxy
168+
result = self.proxyCli.downloadProxy(dn, group, **params)
163169
if not result["OK"]:
164170
err.append(result["Message"])
165171
else:

src/DIRAC/FrameworkSystem/scripts/dirac_login.py

Lines changed: 33 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import DIRAC
2222
from DIRAC import gConfig, gLogger, S_OK, S_ERROR
2323
from DIRAC.Core.Security.Locations import getDefaultProxyLocation, getCertificateAndKeyLocation
24+
from DIRAC.Core.Security.VOMS import VOMS
2425
from DIRAC.Core.Security.ProxyFile import writeToProxyFile
2526
from DIRAC.Core.Security.ProxyInfo import getProxyInfo, formatProxyInfoAsString
2627
from DIRAC.Core.Security.X509Chain import X509Chain # pylint: disable=import-error
@@ -33,6 +34,12 @@
3334
readTokenFromFile,
3435
getTokenFileLocation,
3536
)
37+
from DIRAC.ConfigurationSystem.Client.Helpers.Registry import (
38+
getGroupOption,
39+
getVOMSAttributeForGroup,
40+
getVOMSVOForGroup,
41+
findDefaultGroupForDN,
42+
)
3643

3744
# This value shows what authorization way will be by default
3845
DEFAULT_AUTH_WAY = "certificate" # possible values are "certificate", "diracas"
@@ -240,8 +247,7 @@ def loginWithCertificate(self):
240247

241248
chain = X509Chain()
242249
# Load user cert and key
243-
result = chain.loadChainFromFile(self.certLoc)
244-
if result["OK"]:
250+
if (result := chain.loadChainFromFile(self.certLoc))["OK"]:
245251
result = chain.loadKeyFromFile(
246252
self.keyLoc, password=prompt("Enter Certificate password: ", is_password=True)
247253
)
@@ -259,16 +265,29 @@ def loginWithCertificate(self):
259265

260266
# Create local proxy with group
261267
self.outputFile = self.outputFile or getDefaultProxyLocation()
262-
result = chain.generateProxyToFile(self.outputFile, int(self.lifetime or 12) * 3600, self.group)
268+
parameters = (self.outputFile, int(self.lifetime or 12) * 3600, self.group)
269+
270+
# Add a VOMS extension if the group requires it
271+
if (result := chain.generateProxyToFile(*parameters))["OK"] and (result := self.__enableCS())["OK"]:
272+
if not self.group and (result := findDefaultGroupForDN(credentials["DN"]))["OK"]:
273+
self.group = result["Value"] # Use default group if user don't set it
274+
# based on the configuration we decide whether to add VOMS extensions
275+
if getGroupOption(self.group, "AutoAddVOMS", False):
276+
if not (vomsAttr := getVOMSAttributeForGroup(self.group)):
277+
print(HTML(f"<yellow>No VOMS attribute foud for {self.group}</yellow>"))
278+
else:
279+
vo = getVOMSVOForGroup(self.group)
280+
if not (result := VOMS().setVOMSAttributes(chain, attribute=vomsAttr, vo=vo))["OK"]:
281+
return S_ERROR(f"Failed adding VOMS attribute: {result['Message']}")
282+
chain = result["Value"]
283+
result = chain.generateProxyToFile(*parameters)
263284
if not result["OK"]:
264285
return S_ERROR(f"Couldn't generate proxy: {result['Message']}")
265286

266287
if self.enableCS:
267288
# After creating the proxy, we can try to connect to the server
268-
result = Script.enableCS()
269-
if not result["OK"]:
270-
return S_ERROR(f"Cannot contact CS: {result['Message']}")
271-
gConfig.forceRefresh()
289+
if not (result := self.__enableCS())["OK"]:
290+
return result
272291

273292
# Step 2: Upload proxy to DIRAC server
274293
result = gProxyManager.getUploadedProxyLifeTime(credentials["subject"])
@@ -282,6 +301,11 @@ def loginWithCertificate(self):
282301
return gProxyManager.uploadProxy(proxy)
283302
return S_OK()
284303

304+
def __enableCS(self):
305+
if not (result := Script.enableCS())["OK"] or not (result := gConfig.forceRefresh())["OK"]:
306+
return S_ERROR(f"Cannot contact CS: {result['Message']}")
307+
return result
308+
285309
def howToSwitch(self) -> bool:
286310
"""Helper message, how to switch access type(proxy or access token)"""
287311
if "DIRAC_USE_ACCESS_TOKEN" in self.ENV:
@@ -303,13 +327,10 @@ def howToSwitch(self) -> bool:
303327

304328
def getAuthStatus(self):
305329
"""Try to get user authorization status.
306-
307330
:return: S_OK()/S_ERROR()
308331
"""
309-
result = Script.enableCS()
310-
if not result["OK"]:
311-
return S_ERROR("Cannot contact CS.")
312-
gConfig.forceRefresh()
332+
if not (result := self.__enableCS())["OK"]:
333+
return result
313334

314335
if self.response == "proxy":
315336
result = getProxyInfo(self.outputFile)

0 commit comments

Comments
 (0)