Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Communication] - SDK - Synced SMS and Phone Numbers shared folders #17985

Merged
merged 3 commits into from
Apr 13, 2021
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Sync other shared folder files
  • Loading branch information
jorge-beauregard committed Apr 13, 2021
commit f793e30e4dc3c02b4df402161220efbe76f2b06c
Original file line number Diff line number Diff line change
Expand Up @@ -4,32 +4,39 @@
# license information.
# --------------------------------------------------------------------------
from threading import Lock, Condition
from datetime import datetime, timedelta
from datetime import timedelta
from typing import ( # pylint: disable=unused-import
cast,
Tuple,
)

from msrest.serialization import TZ_UTC
from .utils import get_current_utc_as_int
from .user_token_refresh_options import CommunicationTokenRefreshOptions


class CommunicationTokenCredential(object):
"""Credential type used for authenticating to an Azure Communication service.
:param communication_token_refresh_options: The token used to authenticate to an Azure Communication service
:type communication_token_refresh_options: ~azure.communication.chat.CommunicationTokenRefreshOptions
:param str token: The token used to authenticate to an Azure Communication service
:keyword token_refresher: The token refresher to provide capacity to fetch fresh token
:raises: TypeError
"""

ON_DEMAND_REFRESHING_INTERVAL_MINUTES = 2
_ON_DEMAND_REFRESHING_INTERVAL_MINUTES = 2

def __init__(self,
communication_token_refresh_options
):
token, # type: str
**kwargs
):
token_refresher = kwargs.pop('token_refresher', None)
communication_token_refresh_options = CommunicationTokenRefreshOptions(token=token,
token_refresher=token_refresher)
self._token = communication_token_refresh_options.get_token()
self._token_refresher = communication_token_refresh_options.get_token_refresher()
self._lock = Condition(Lock())
self._some_thread_refreshing = False

def get_token(self):
# type () -> ~azure.core.credentials.AccessToken
def get_token(self, *scopes, **kwargs): # pylint: disable=unused-argument
# type (*str, **Any) -> AccessToken
"""The value of the configured token.
:rtype: ~azure.core.credentials.AccessToken
"""
Expand All @@ -53,7 +60,7 @@ def get_token(self):

if should_this_thread_refresh:
try:
newtoken = self._token_refresher()
newtoken = self._token_refresher() # pylint:disable=not-callable

with self._lock:
self._token = newtoken
Expand All @@ -72,12 +79,8 @@ def _wait_till_inprogress_thread_finish_refreshing(self):
self._lock.acquire()

def _token_expiring(self):
return self._token.expires_on - self._get_utc_now() <\
timedelta(minutes=self.ON_DEMAND_REFRESHING_INTERVAL_MINUTES)
return self._token.expires_on - get_current_utc_as_int() <\
timedelta(minutes=self._ON_DEMAND_REFRESHING_INTERVAL_MINUTES).total_seconds()

def _is_currenttoken_valid(self):
return self._get_utc_now() < self._token.expires_on

@classmethod
def _get_utc_now(cls):
return datetime.now().replace(tzinfo=TZ_UTC)
return get_current_utc_as_int() < self._token.expires_on
Original file line number Diff line number Diff line change
Expand Up @@ -4,50 +4,53 @@
# license information.
# --------------------------------------------------------------------------
from asyncio import Condition, Lock
from datetime import datetime, timedelta
from datetime import timedelta
from typing import ( # pylint: disable=unused-import
cast,
Tuple,
Any
)

from msrest.serialization import TZ_UTC
from .utils import get_current_utc_as_int
from .user_token_refresh_options import CommunicationTokenRefreshOptions


class CommunicationTokenCredential(object):
"""Credential type used for authenticating to an Azure Communication service.
:param communication_token_refresh_options: The token used to authenticate to an Azure Communication service
:type communication_token_refresh_options: ~azure.communication.chat.aio.CommunicationTokenRefreshOptions
:param str token: The token used to authenticate to an Azure Communication service
:keyword token_refresher: The async token refresher to provide capacity to fetch fresh token
:raises: TypeError
"""

ON_DEMAND_REFRESHING_INTERVAL_MINUTES = 2
_ON_DEMAND_REFRESHING_INTERVAL_MINUTES = 2

def __init__(self,
communication_token_refresh_options
):
def __init__(self, token: str, **kwargs: Any):
token_refresher = kwargs.pop('token_refresher', None)
communication_token_refresh_options = CommunicationTokenRefreshOptions(token=token,
token_refresher=token_refresher)
self._token = communication_token_refresh_options.get_token()
self._token_refresher = communication_token_refresh_options.get_token_refresher()
self._lock = Condition(Lock())
self._some_thread_refreshing = False

def get_token(self):
# type () -> ~azure.core.credentials.AccessToken
async def get_token(self, *scopes, **kwargs): # pylint: disable=unused-argument
# type (*str, **Any) -> AccessToken
"""The value of the configured token.
:rtype: ~azure.core.credentials.AccessToken
"""

if not self._token_refresher or not self._token_expiring():
return self._token

should_this_thread_refresh = False

with self._lock:
async with self._lock:

while self._token_expiring():
if self._some_thread_refreshing:
if self._is_currenttoken_valid():
return self._token

self._wait_till_inprogress_thread_finish_refreshing()
await self._wait_till_inprogress_thread_finish_refreshing()
else:
should_this_thread_refresh = True
self._some_thread_refreshing = True
Expand All @@ -56,32 +59,37 @@ def get_token(self):

if should_this_thread_refresh:
try:
newtoken = self._token_refresher()
newtoken = await self._token_refresher() # pylint:disable=not-callable

with self._lock:
async with self._lock:
self._token = newtoken
self._some_thread_refreshing = False
self._lock.notify_all()
except:
with self._lock:
async with self._lock:
self._some_thread_refreshing = False
self._lock.notify_all()

raise

return self._token

def _wait_till_inprogress_thread_finish_refreshing(self):
async def _wait_till_inprogress_thread_finish_refreshing(self):
self._lock.release()
self._lock.acquire()
await self._lock.acquire()

def _token_expiring(self):
return self._token.expires_on - self._get_utc_now() <\
timedelta(minutes=self.ON_DEMAND_REFRESHING_INTERVAL_MINUTES)
return self._token.expires_on - get_current_utc_as_int() <\
timedelta(minutes=self._ON_DEMAND_REFRESHING_INTERVAL_MINUTES).total_seconds()

def _is_currenttoken_valid(self):
return self._get_utc_now() < self._token.expires_on
return get_current_utc_as_int() < self._token.expires_on

async def close(self) -> None:
pass

async def __aenter__(self):
return self

@classmethod
def _get_utc_now(cls):
return datetime.now().replace(tzinfo=TZ_UTC)
async def __aexit__(self, *args):
await self.close()
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
from msrest.serialization import TZ_UTC
from azure.core.credentials import AccessToken


def _convert_datetime_to_utc_int(expires_on):
epoch = time.mktime(datetime(1970, 1, 1).timetuple())
return epoch-time.mktime(expires_on.timetuple())
Expand Down Expand Up @@ -50,6 +51,7 @@ def get_current_utc_time():
# type: () -> str
return str(datetime.utcnow().strftime("%a, %d %b %Y %H:%M:%S ")) + "GMT"


def get_current_utc_as_int():
# type: () -> int
current_utc_datetime = datetime.utcnow().replace(tzinfo=TZ_UTC)
Expand Down Expand Up @@ -113,7 +115,3 @@ def get_authentication_policy(

raise TypeError("Unsupported credential: {}. Use an access token string to use HMACCredentialsPolicy"
"or a token credential from azure.identity".format(type(credential)))

def _convert_expires_on_datetime_to_utc_int(expires_on):
epoch = time.mktime(datetime(1970, 1, 1).timetuple())
return epoch-time.mktime(expires_on.timetuple())
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@
]),
install_requires=[
"msrest>=0.6.0",
"azure-core<2.0.0,>=1.9.0",
'azure-core<2.0.0,>=1.11.0',
],
extras_require={
":python_version<'3.0'": ['azure-communication-nspkg'],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,32 +4,39 @@
# license information.
# --------------------------------------------------------------------------
from threading import Lock, Condition
from datetime import datetime, timedelta
from datetime import timedelta
from typing import ( # pylint: disable=unused-import
cast,
Tuple,
)

from msrest.serialization import TZ_UTC
from .utils import get_current_utc_as_int
from .user_token_refresh_options import CommunicationTokenRefreshOptions


class CommunicationTokenCredential(object):
"""Credential type used for authenticating to an Azure Communication service.
:param communication_token_refresh_options: The token used to authenticate to an Azure Communication service
:type communication_token_refresh_options: ~azure.communication.chat.CommunicationTokenRefreshOptions
:param str token: The token used to authenticate to an Azure Communication service
:keyword token_refresher: The token refresher to provide capacity to fetch fresh token
:raises: TypeError
"""

ON_DEMAND_REFRESHING_INTERVAL_MINUTES = 2
_ON_DEMAND_REFRESHING_INTERVAL_MINUTES = 2

def __init__(self,
communication_token_refresh_options
):
token, # type: str
**kwargs
):
token_refresher = kwargs.pop('token_refresher', None)
communication_token_refresh_options = CommunicationTokenRefreshOptions(token=token,
token_refresher=token_refresher)
self._token = communication_token_refresh_options.get_token()
self._token_refresher = communication_token_refresh_options.get_token_refresher()
self._lock = Condition(Lock())
self._some_thread_refreshing = False

def get_token(self):
# type () -> ~azure.core.credentials.AccessToken
def get_token(self, *scopes, **kwargs): # pylint: disable=unused-argument
# type (*str, **Any) -> AccessToken
"""The value of the configured token.
:rtype: ~azure.core.credentials.AccessToken
"""
Expand All @@ -53,7 +60,7 @@ def get_token(self):

if should_this_thread_refresh:
try:
newtoken = self._token_refresher()
newtoken = self._token_refresher() # pylint:disable=not-callable

with self._lock:
self._token = newtoken
Expand All @@ -72,12 +79,8 @@ def _wait_till_inprogress_thread_finish_refreshing(self):
self._lock.acquire()

def _token_expiring(self):
return self._token.expires_on - self._get_utc_now() <\
timedelta(minutes=self.ON_DEMAND_REFRESHING_INTERVAL_MINUTES)
return self._token.expires_on - get_current_utc_as_int() <\
timedelta(minutes=self._ON_DEMAND_REFRESHING_INTERVAL_MINUTES).total_seconds()

def _is_currenttoken_valid(self):
return self._get_utc_now() < self._token.expires_on

@classmethod
def _get_utc_now(cls):
return datetime.now().replace(tzinfo=TZ_UTC)
return get_current_utc_as_int() < self._token.expires_on
Loading