diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index b5c4d935..ee45273b 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -493,7 +493,7 @@ The values can be found in the Azure AD configuration page. Short explanation of - `WEBVIZ_TENANT_ID`: The organization's Azure tenant ID (Equinor has exactly one tenant ID). - `WEBVIZ_CLIENT_ID`: ID of the Webviz Azure AD app. - `WEBVIZ_CLIENT_SECRET`: Webviz Azure AD app's client secret. -- `WEBVIZ_SCOPE`: The API permission for this Webviz Azure AD app. +- `WEBVIZ_SCOPE`: The API permission for this Webviz Azure AD app. If there are more than one scopes, use comma (`,`) to separate them. Note that only multiple scopes from one resource/API is currently supported. If you are serving behind a proxy, you might need to configure trust for X-FORWARD headers. Internally, this is done by using a ProxyFix class, as described in the Flask [docs](https://flask.palletsprojects.com/en/2.0.x/deploying/wsgi-standalone/#proxy-setups). To enable the use of the ProxyFix class, set one or all of the following variables to an integer describing the number of trusted forwards: diff --git a/webviz_config/_oauth2.py b/webviz_config/_oauth2.py index bdac30c7..a54014b3 100644 --- a/webviz_config/_oauth2.py +++ b/webviz_config/_oauth2.py @@ -19,7 +19,8 @@ def __init__(self, app: flask.app.Flask): self._tenant_id = os.environ["WEBVIZ_TENANT_ID"] self._client_id = os.environ["WEBVIZ_CLIENT_ID"] self._client_secret = os.environ["WEBVIZ_CLIENT_SECRET"] - self._scope = os.environ["WEBVIZ_SCOPE"] + scope_raw = os.environ["WEBVIZ_SCOPE"] + self._scope = [scope.strip() for scope in scope_raw.split(",")] # Initiate msal self._msal_app = msal.ConfidentialClientApplication( @@ -68,7 +69,7 @@ def _login_controller(): # type: ignore[no-untyped-def] # First leg of Oauth2 authorization code flow auth_url = self._msal_app.get_authorization_request_url( - scopes=[self._scope], redirect_uri=redirect_uri + scopes=self._scope, redirect_uri=redirect_uri ) return flask.redirect(auth_url) @@ -88,7 +89,7 @@ def _auth_return_controller(): # type: ignore[no-untyped-def] # Second leg of Oauth2 authorization code flow tokens_result = self._msal_app.acquire_token_by_authorization_code( - code=code, scopes=[self._scope], redirect_uri=redirect_uri + code=code, scopes=self._scope, redirect_uri=redirect_uri ) expires_in = tokens_result.get("expires_in") expiration_date = datetime.datetime.now( @@ -170,7 +171,7 @@ def refresh_token_if_possible(self) -> Tuple[str, datetime.datetime]: if not self._accounts: self._accounts = self._msal_app.get_accounts() renewed_tokens_result = self._msal_app.acquire_token_silent( - scopes=[self._scope], account=self._accounts[0] + scopes=self._scope, account=self._accounts[0] ) expires_in = renewed_tokens_result.get("expires_in") new_expiration_date = datetime.datetime.now(