Skip to content

Commit

Permalink
feat (ProxyManager): query DiracX for a token
Browse files Browse the repository at this point in the history
  • Loading branch information
chaen committed Sep 27, 2023
1 parent 4849196 commit 4086cc3
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 34 deletions.
10 changes: 10 additions & 0 deletions src/DIRAC/Core/scripts/dirac_configure.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ def __init__(self):
self.outputFile = ""
self.skipVOMSDownload = False
self.extensions = ""
self.legacyExchangeApiKey = ""

def setGateway(self, optionValue):
self.gatewayServer = optionValue
Expand Down Expand Up @@ -174,6 +175,12 @@ def setIssuer(self, optionValue):
DIRAC.gConfig.setOptionValue("/DIRAC/Security/Authorization/issuer", self.issuer)
return DIRAC.S_OK()

def setLegacyExchangeApiKey(self, optionValue):
self.legacyExchangeApiKey = optionValue
Script.localCfg.addDefaultEntry("/DiracX/LegacyExchangeApiKey", self.legacyExchangeApiKey)
DIRAC.gConfig.setOptionValue(cfgInstallPath("LegacyExchangeApiKey"), self.vo)
return DIRAC.S_OK()


def _runConfigurationWizard(setups, defaultSetup):
"""The implementation of the configuration wizard"""
Expand Down Expand Up @@ -361,6 +368,9 @@ def runDiracConfigure(params):
Script.registerSwitch("n:", "SiteName=", "Set <sitename> as DIRAC Site Name", params.setSiteName)
Script.registerSwitch("N:", "CEName=", "Set <cename> as Computing Element name", params.setCEName)
Script.registerSwitch("V:", "VO=", "Set the VO name", params.setVO)
Script.registerSwitch(
"K:", "LegacyExchangeApiKey=", "Set the Api Key to talk to DiracX", params.setLegacyExchangeApiKey
)

Script.registerSwitch("W:", "gateway=", "Configure <gateway> as DIRAC Gateway for the site", params.setGateway)

Expand Down
61 changes: 28 additions & 33 deletions src/DIRAC/FrameworkSystem/Service/ProxyManagerHandler.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@
:caption: ProxyManager options
"""

from DIRAC import gLogger, S_OK, S_ERROR
import os
import requests
from DIRAC import gLogger, S_OK, S_ERROR, gConfig
from DIRAC.Core.DISET.RequestHandler import RequestHandler, getServiceOption
from DIRAC.Core.Security import Properties
from DIRAC.Core.Utilities.ObjectLoader import ObjectLoader
Expand Down Expand Up @@ -411,39 +413,32 @@ def export_getVOMSProxyWithToken(self, userDN, userGroup, requestPem, requiredLi

def export_exchangeProxyForToken(self):
"""Exchange a proxy for an equivalent token to be used with diracx"""
try:
from diracx.routers.auth import ( # pylint: disable=import-error
AuthSettings,
create_token,
TokenResponse,
) # pylint: disable=import-error

authSettings = AuthSettings()

from uuid import uuid4

credDict = self.getRemoteCredentials()
vo = Registry.getVOForGroup(credDict["group"])
payload = {
"sub": f"{vo}:{credDict['username']}",
"vo": vo,
"aud": authSettings.token_audience,
"iss": authSettings.token_issuer,
"dirac_properties": list(
set(credDict.get("groupProperties", [])) | set(credDict.get("properties", []))
),
"jti": str(uuid4()),

from diracx.core.preferences import get_diracx_preferences

apiKey = gConfig.getValue("/DiracX/LegacyExchangeApiKey")
if not apiKey:
return S_ERROR("Missing mandatory /DiracX/LegacyExchangeApiKey configuration")

diracxUrl = get_diracx_preferences().url

credDict = self.getRemoteCredentials()
vo = Registry.getVOForGroup(credDict["group"])
dirac_properties = list(set(credDict.get("groupProperties", [])) | set(credDict.get("properties", [])))
group = credDict["group"]
scopes = [f"vo:{vo}", f"group:{group}", [f"property:{prop}" for prop in dirac_properties]]

r = requests.get(
f"{diracxUrl}/auth/legacy-exchange",
params={
"preferred_username": credDict["username"],
"dirac_group": credDict["group"],
}
return S_OK(
TokenResponse(
access_token=create_token(payload, authSettings),
expires_in=authSettings.access_token_expire_minutes * 60,
).dict()
)
except Exception as e:
return S_ERROR(f"Could not get token: {e!r}")
"scopes": " ".join(scopes),
},
headers={"Authorization": f"Bearer {apiKey}"},
)

r.raise_for_status()
return S_OK(r.json())


class ProxyManagerHandler(ProxyManagerHandlerMixin, RequestHandler):
Expand Down
2 changes: 2 additions & 0 deletions tests/CI/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,8 @@ services:
- DIRACX_DB_URL_JOBDB=mysql+aiomysql://Dirac:Dirac@mysql/JobDB
- DIRACX_SERVICE_AUTH_TOKEN_KEY=file:///signing-key/rs256.key
- DIRACX_SERVICE_AUTH_ALLOWED_REDIRECTS=["http://diracx:8000/docs/oauth2-redirect"]
# Obtained with echo 'InsecureChangeMe' | base64 -d | openssl sha512
- DIRACX_LEGACY_EXCHANGE_HASHED_API_KEY=07cddf6948d316ac9d186544dc3120c4c6697d8f994619665985c0a5bf76265a
ports:
- 8000:8000
depends_on:
Expand Down
2 changes: 1 addition & 1 deletion tests/Jenkins/dirac_ci.sh
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ installSite() {

echo "==> Done installing, now configuring"
source "${SERVERINSTALLDIR}/bashrc"
if ! dirac-configure --cfg "${SERVERINSTALLDIR}/install.cfg" "${DEBUG}"; then
if ! dirac-configure --cfg "${SERVERINSTALLDIR}/install.cfg" --LegacyExchangeApiKey='InsecureChangeMe' "${DEBUG}"; then
echo "ERROR: dirac-configure failed" >&2
exit 1
fi
Expand Down

0 comments on commit 4086cc3

Please sign in to comment.