Skip to content

Commit 131b2ec

Browse files
committed
Updated pr.
1 parent 3ebfc4f commit 131b2ec

File tree

3 files changed

+14
-182
lines changed

3 files changed

+14
-182
lines changed

ads/common/auth.py

Lines changed: 10 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -860,74 +860,24 @@ def _validate_and_refresh_token(self, configuration: Dict[str, Any]):
860860

861861
if not security_token_container.valid():
862862
raise SecurityTokenError(
863-
"Security token is invalid or has expired. Call `oci session authenticate` to generate new session."
863+
"Security token has expired. Call `oci session authenticate` to generate new session."
864864
)
865865

866866
time_now = int(time.time())
867867
time_expired = security_token_container.get_jwt()["exp"]
868868
if time_now - time_expired < SECURITY_TOKEN_LEFT_TIME:
869-
try:
870-
self._refresh_security_token(configuration)
871-
except Exception as ex:
872-
logger.info("Failed to refresh security token. Error: {}".format(ex))
869+
if not self.oci_config_location:
870+
logger.warning("Can not auto-refresh token. Specify parameter `oci_config_location` through ads.set_auth() or ads.auth.create_signer().")
871+
else:
872+
result = os.system(f"oci session refresh --config-file {self.oci_config_location} --profile {self.oci_key_profile}")
873+
if result == 1:
874+
logger.warning(
875+
"Some error happened during auto-refreshing the token. Continue using the current one that's expiring in less than {SECURITY_TOKEN_LEFT_TIME} seconds."
876+
"Please follow steps in https://docs.oracle.com/en-us/iaas/Content/API/SDKDocs/clitoken.htm to renew token."
877+
)
873878

874879
date_time = datetime.fromtimestamp(time_expired).strftime("%Y-%m-%d %H:%M:%S")
875880
logger.info(f"Session is valid until {date_time}.")
876-
877-
def _refresh_security_token(self, configuration: Dict[str, Any]):
878-
"""Refreshes security token. The logic is mainly taken reference from:
879-
https://github.com/oracle/oci-cli/blob/master/src/oci_cli/cli_session.py#L152
880-
881-
Parameters
882-
----------
883-
configuration: Dict
884-
Security token configuration.
885-
"""
886-
expanded_security_token_location = os.path.expanduser(
887-
configuration.get("security_token_file")
888-
)
889-
890-
with open(expanded_security_token_location, 'r') as security_token_file:
891-
token = security_token_file.read()
892-
893-
try:
894-
private_key = oci.signer.load_private_key_from_file(
895-
configuration.get("key_file"), configuration.get("pass_phrase")
896-
)
897-
except:
898-
raise
899-
auth = oci.auth.signers.SecurityTokenSigner(token, private_key)
900-
901-
refresh_url = "{endpoint}/v1/authentication/refresh".format(
902-
endpoint=oci.regions.endpoint_for("auth", configuration.get("region"))
903-
)
904-
logger.info(f"Attempting to refresh token from {refresh_url}.")
905-
906-
response = requests.post(
907-
refresh_url,
908-
headers={
909-
'content-type': 'application/json'
910-
},
911-
data=json.dumps({
912-
'currentToken': token
913-
}),
914-
auth=auth
915-
)
916-
917-
if response.status_code == 200:
918-
refreshed_token = json.loads(response.content.decode('UTF-8'))['token']
919-
with open(expanded_security_token_location, 'w') as security_token_file:
920-
security_token_file.write(refreshed_token)
921-
utils.apply_user_only_access_permissions(expanded_security_token_location)
922-
logger.info("Successfully refreshed token")
923-
elif response.status_code == 401:
924-
raise SecurityTokenError(
925-
"Security token has expired. Call `oci session authenticate` to generate new session."
926-
)
927-
else:
928-
raise SecurityTokenError(
929-
"Failed to refresh sesison. Error: {}".format(str(response.content.decode('UTF-8')))
930-
)
931881

932882
def _read_security_token_file(self, security_token_file: str) -> str:
933883
"""Reads security token from file.

ads/common/utils.py

Lines changed: 0 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,7 @@
1717
import random
1818
import re
1919
import shutil
20-
import stat
2120
import string
22-
import subprocess
2321
import sys
2422
import tempfile
2523
from datetime import datetime
@@ -1601,58 +1599,3 @@ def is_path_exists(uri: str, auth: Optional[Dict] = None) -> bool:
16011599
if fsspec.filesystem(path_scheme, **storage_options).exists(uri):
16021600
return True
16031601
return False
1604-
1605-
def apply_user_only_access_permissions(path: str):
1606-
"""Applies user-only access permission to path. The logic is mainly taken reference from:
1607-
https://github.com/oracle/oci-cli/blob/master/src/oci_cli/cli_util.py#L2555
1608-
1609-
Parameters
1610-
----------
1611-
path: str
1612-
Path to the file or folder
1613-
"""
1614-
if not os.path.exists(path):
1615-
raise RuntimeError("Failed attempting to set permissions on path that does not exist: {}".format(path))
1616-
1617-
if is_windows():
1618-
# General permissions strategy is:
1619-
# - if we create a new folder (e.g. C:\Users\opc\.oci), set access to allow full control for current user and no access for anyone else
1620-
# - if we create a new file, set access to allow full control for current user and no access for anyone else
1621-
# - thus if the user elects to place a new file (config or key) in an existing directory, we will not change the
1622-
# permissions of that directory but will explicitly set the permissions on that file
1623-
username = os.environ['USERNAME']
1624-
userdomain = os.environ['UserDomain']
1625-
userWithDomain = os.environ['USERNAME']
1626-
if userdomain:
1627-
userWithDomain = userdomain + "\\" + username
1628-
admin_grp = '*S-1-5-32-544'
1629-
system_usr = '*S-1-5-18'
1630-
try:
1631-
if os.path.isfile(path):
1632-
subprocess.check_output('icacls "{path}" /reset'.format(path=path), stderr=subprocess.STDOUT)
1633-
try:
1634-
subprocess.check_output('icacls "{path}" /inheritance:r /grant:r "{username}:F" /grant {admin_grp}:F /grant {system_usr}:F'.format(path=path, username=userWithDomain, admin_grp=admin_grp, system_usr=system_usr), stderr=subprocess.STDOUT)
1635-
except subprocess.CalledProcessError:
1636-
subprocess.check_output('icacls "{path}" /inheritance:r /grant:r "{username}:F" /grant {admin_grp}:F /grant {system_usr}:F'.format(path=path, username=username, admin_grp=admin_grp, system_usr=system_usr), stderr=subprocess.STDOUT)
1637-
else:
1638-
if os.listdir(path):
1639-
# safety check to make sure we aren't changing permissions of existing files
1640-
raise RuntimeError("Failed attempting to set permissions on existing folder that is not empty.")
1641-
subprocess.check_output('icacls "{path}" /reset'.format(path=path), stderr=subprocess.STDOUT)
1642-
try:
1643-
subprocess.check_output('icacls "{path}" /inheritance:r /grant:r "{username}:(OI)(CI)F" /grant:r {admin_grp}:(OI)(CI)F /grant:r {system_usr}:(OI)(CI)F'.format(path=path, username=userWithDomain, admin_grp=admin_grp, system_usr=system_usr), stderr=subprocess.STDOUT)
1644-
except subprocess.CalledProcessError:
1645-
subprocess.check_output('icacls "{path}" /inheritance:r /grant:r "{username}:(OI)(CI)F" /grant:r {admin_grp}:(OI)(CI)F /grant:r {system_usr}:(OI)(CI)F'.format(path=path, username=username, admin_grp=admin_grp, system_usr=system_usr), stderr=subprocess.STDOUT)
1646-
except subprocess.CalledProcessError as exc_info:
1647-
print("Error occurred while attempting to set permissions for {path}: {exception}".format(path=path, exception=str(exc_info)))
1648-
sys.exit(exc_info.returncode)
1649-
else:
1650-
if os.path.isfile(path):
1651-
os.chmod(path, stat.S_IRUSR | stat.S_IWUSR)
1652-
else:
1653-
# For directories, we need to apply S_IXUSER otherwise it looks like on Linux/Unix/macOS if we create the directory then
1654-
# it won't behave like a directory and let files be put into it
1655-
os.chmod(path, stat.S_IRUSR | stat.S_IWUSR | stat.S_IXUSR)
1656-
1657-
def is_windows():
1658-
return sys.platform == 'win32' or sys.platform == 'cygwin'

tests/unitary/default_setup/auth/test_auth.py

Lines changed: 4 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -586,7 +586,7 @@ def test_security_token(
586586
assert signer["config"]["key_file"] == "test_key_file"
587587
assert isinstance(signer["signer"], SecurityTokenSigner)
588588

589-
@mock.patch("ads.common.auth.SecurityToken._refresh_security_token")
589+
@mock.patch("os.system")
590590
@mock.patch("oci.auth.security_token_container.SecurityTokenContainer.get_jwt")
591591
@mock.patch("time.time")
592592
@mock.patch("oci.auth.security_token_container.SecurityTokenContainer.valid")
@@ -599,7 +599,7 @@ def test_validate_and_refresh_token(
599599
mock_valid,
600600
mock_time,
601601
mock_get_jwt,
602-
mock_refresh_security_token
602+
mock_system
603603
):
604604
security_token = SecurityToken(
605605
args={
@@ -625,79 +625,18 @@ def test_validate_and_refresh_token(
625625
):
626626
security_token._validate_and_refresh_token(configuration)
627627

628-
629628
mock_valid.return_value = True
630629
mock_time.return_value = 1
631630
mock_get_jwt.return_value = {"exp" : 1}
631+
mock_system.return_value = 1
632632

633633
security_token._validate_and_refresh_token(configuration)
634634

635635
mock_read_security_token_file.assert_called_with("test_security_token")
636636
mock_security_token_container.assert_called()
637637
mock_time.assert_called()
638638
mock_get_jwt.assert_called()
639-
mock_refresh_security_token.assert_called_with(configuration)
640-
641-
@mock.patch("ads.common.utils.apply_user_only_access_permissions")
642-
@mock.patch("json.loads")
643-
@mock.patch("requests.post")
644-
@mock.patch("json.dumps")
645-
@mock.patch("oci.auth.signers.SecurityTokenSigner.__init__")
646-
@mock.patch("oci.signer.load_private_key_from_file")
647-
@mock.patch("builtins.open")
648-
def test_refresh_security_token(
649-
self,
650-
mock_open,
651-
mock_load_private_key_from_file,
652-
mock_security_token_signer,
653-
mock_dumps,
654-
mock_post,
655-
mock_loads,
656-
mock_apply_user_only_access_permissions
657-
):
658-
security_token = SecurityToken(args={})
659-
configuration = {
660-
"fingerprint": "test_fingerprint",
661-
"tenancy": "test_tenancy",
662-
"region": "us-ashburn-1",
663-
"key_file": "test_key_file",
664-
"security_token_file": "test_security_token",
665-
"generic_headers": [1,2,3],
666-
"body_headers": [4,5,6]
667-
}
668-
mock_security_token_signer.return_value = None
669-
mock_loads.return_value = {
670-
"token": "test_token"
671-
}
672-
673-
response = MagicMock()
674-
response.status_code = 401
675-
mock_post.return_value = response
676-
with pytest.raises(
677-
SecurityTokenError,
678-
match="Security token has expired. Call `oci session authenticate` to generate new session."
679-
):
680-
security_token._refresh_security_token(configuration)
681-
682-
response.status_code = 500
683-
mock_post.return_value = response
684-
with pytest.raises(
685-
SecurityTokenError,
686-
):
687-
security_token._refresh_security_token(configuration)
688-
689-
response.status_code = 200
690-
response.content = bytes("test_content", encoding='utf8')
691-
mock_post.return_value = response
692-
security_token._refresh_security_token(configuration)
693-
694-
mock_open.assert_called()
695-
mock_load_private_key_from_file.assert_called_with("test_key_file", None)
696-
mock_security_token_signer.assert_called()
697-
mock_dumps.assert_called()
698-
mock_post.assert_called()
699-
mock_loads.assert_called()
700-
mock_apply_user_only_access_permissions.assert_called()
639+
mock_system.assert_called_with(f"oci session refresh --config-file {DEFAULT_LOCATION} --profile test_profile")
701640

702641
@mock.patch("builtins.open")
703642
@mock.patch("os.path.isfile")

0 commit comments

Comments
 (0)