mirror of
https://github.com/fuckpiracyshield/service.git
synced 2024-11-23 21:50:45 +01:00
Reworked some parts of the code and moved some logic here instead of leaving it in the API.
This commit is contained in:
parent
6ce487888a
commit
c82d4683b9
20 changed files with 1075 additions and 36 deletions
1
src/piracyshield_service/account/session/__init__.py
Normal file
1
src/piracyshield_service/account/session/__init__.py
Normal file
|
@ -0,0 +1 @@
|
|||
|
69
src/piracyshield_service/account/session/create.py
Normal file
69
src/piracyshield_service/account/session/create.py
Normal file
|
@ -0,0 +1,69 @@
|
|||
from __future__ import annotations
|
||||
|
||||
from piracyshield_service.base import BaseService
|
||||
|
||||
from piracyshield_component.config import Config
|
||||
from piracyshield_component.exception import ApplicationException
|
||||
|
||||
from piracyshield_data_storage.account.session.memory import AccountSessionMemory, AccountSessionMemorySetException, AccountSessionMemoryGetException
|
||||
|
||||
from piracyshield_service.account.session.create_long_session import AccountSessionCreateLongSessionService
|
||||
from piracyshield_service.account.session.create_short_session import AccountSessionCreateShortSessionService
|
||||
|
||||
class AccountSessionCreateService(BaseService):
|
||||
|
||||
"""
|
||||
Records a session.
|
||||
|
||||
We use the refresh token as the root of all the generated tokens, so we don't invalidate other ongoing sessions by saving them all indiscriminately.
|
||||
"""
|
||||
|
||||
account_session_create_short_session_service = None
|
||||
|
||||
account_session_create_long_session_service = None
|
||||
|
||||
def __init__(self):
|
||||
"""
|
||||
Inizialize logger and required modules.
|
||||
"""
|
||||
|
||||
super().__init__()
|
||||
|
||||
self._prepare_configs()
|
||||
|
||||
self._prepare_modules()
|
||||
|
||||
def execute(self, refresh_token: str, access_token: str, account_id: str, ip_address: str) -> bool | Exception:
|
||||
self.account_session_create_long_session_service.execute(
|
||||
refresh_token = refresh_token,
|
||||
access_token = access_token,
|
||||
account_id = account_id,
|
||||
ip_address = ip_address
|
||||
)
|
||||
|
||||
self.account_session_create_short_session_service.execute(
|
||||
refresh_token = refresh_token,
|
||||
access_token = access_token,
|
||||
account_id = account_id,
|
||||
ip_address = ip_address
|
||||
)
|
||||
|
||||
return True
|
||||
|
||||
def _schedule_task(self):
|
||||
pass
|
||||
|
||||
def _validate_parameters(self):
|
||||
pass
|
||||
|
||||
def _prepare_configs(self):
|
||||
pass
|
||||
|
||||
def _prepare_modules(self) -> None:
|
||||
"""
|
||||
Initialize and set the instances.
|
||||
"""
|
||||
|
||||
self.account_session_create_long_session_service = AccountSessionCreateLongSessionService()
|
||||
|
||||
self.account_session_create_short_session_service = AccountSessionCreateShortSessionService()
|
|
@ -0,0 +1,86 @@
|
|||
from __future__ import annotations
|
||||
|
||||
from piracyshield_service.base import BaseService
|
||||
|
||||
from piracyshield_component.config import Config
|
||||
from piracyshield_component.utils.time import Time
|
||||
from piracyshield_component.exception import ApplicationException
|
||||
|
||||
from piracyshield_data_storage.account.session.memory import AccountSessionMemory, AccountSessionMemorySetException, AccountSessionMemoryGetException
|
||||
|
||||
from piracyshield_service.account.errors import AccountErrorCode, AccountErrorMessage
|
||||
|
||||
from datetime import timedelta
|
||||
|
||||
class AccountSessionCreateLongSessionService(BaseService):
|
||||
|
||||
"""
|
||||
Records a long session.
|
||||
"""
|
||||
|
||||
jwt_token_config = None
|
||||
|
||||
session_config = None
|
||||
|
||||
data_memory = None
|
||||
|
||||
def __init__(self):
|
||||
"""
|
||||
Inizialize logger and required modules.
|
||||
"""
|
||||
|
||||
super().__init__()
|
||||
|
||||
self._prepare_configs()
|
||||
|
||||
self._prepare_modules()
|
||||
|
||||
def execute(self, refresh_token: str, access_token: str, account_id: str, ip_address: str) -> bool | Exception:
|
||||
# TODO: should we unpack the tokens and set their really real create and expire datetimes?
|
||||
|
||||
now = Time.now()
|
||||
|
||||
# save the refresh token as a long session
|
||||
long_session_response = self.data_memory.add_long_session(
|
||||
account_id = account_id,
|
||||
refresh_token = refresh_token,
|
||||
data = {
|
||||
'ip_address': ip_address,
|
||||
'created_at': str(now), # roughly accurate
|
||||
'expires_at': str(now + timedelta(seconds = self.jwt_token_config.get('refresh_expiration_time')))
|
||||
},
|
||||
duration = self.jwt_token_config.get('refresh_expiration_time')
|
||||
)
|
||||
|
||||
if not long_session_response:
|
||||
self.logger.error(f"Could not create a long session for `{account_id}`")
|
||||
|
||||
raise ApplicationException(AccountErrorCode.GENERIC, AccountErrorMessage.GENERIC)
|
||||
|
||||
self.logger.debug(f"Long session created for `{account_id}`")
|
||||
|
||||
return True
|
||||
|
||||
def _schedule_task(self):
|
||||
pass
|
||||
|
||||
def _validate_parameters(self):
|
||||
pass
|
||||
|
||||
def _prepare_configs(self) -> None:
|
||||
"""
|
||||
Loads the configs.
|
||||
"""
|
||||
|
||||
self.session_config = Config('security/session')
|
||||
|
||||
self.jwt_token_config = Config('security/token').get('jwt_token')
|
||||
|
||||
def _prepare_modules(self) -> None:
|
||||
"""
|
||||
Initialize and set the instances.
|
||||
"""
|
||||
|
||||
self.data_memory = AccountSessionMemory(
|
||||
database = self.session_config.get('database').get('memory_database')
|
||||
)
|
|
@ -0,0 +1,90 @@
|
|||
from __future__ import annotations
|
||||
|
||||
from piracyshield_service.base import BaseService
|
||||
|
||||
from piracyshield_component.config import Config
|
||||
from piracyshield_component.utils.time import Time
|
||||
from piracyshield_component.exception import ApplicationException
|
||||
|
||||
from piracyshield_data_storage.account.session.memory import AccountSessionMemory, AccountSessionMemorySetException, AccountSessionMemoryGetException
|
||||
|
||||
from piracyshield_service.account.errors import AccountErrorCode, AccountErrorMessage
|
||||
|
||||
from datetime import timedelta
|
||||
|
||||
class AccountSessionCreateShortSessionService(BaseService):
|
||||
|
||||
"""
|
||||
Records a short session.
|
||||
"""
|
||||
|
||||
jwt_token_config = None
|
||||
|
||||
session_config = None
|
||||
|
||||
data_memory = None
|
||||
|
||||
def __init__(self):
|
||||
"""
|
||||
Inizialize logger and required modules.
|
||||
"""
|
||||
|
||||
super().__init__()
|
||||
|
||||
self._prepare_configs()
|
||||
|
||||
self._prepare_modules()
|
||||
|
||||
def execute(self, refresh_token: str, access_token: str, account_id: str, ip_address: str) -> bool | Exception:
|
||||
# TODO: should we unpack the tokens and set their really real create and expire datetimes?
|
||||
|
||||
now = Time.now()
|
||||
|
||||
# short sessions could have been stored in a list, but because they all have different expire times,
|
||||
# and we don't want to expire them manually (automatically is something not yet possible in Redis),
|
||||
# we will store them in a string
|
||||
short_session_response = self.data_memory.add_short_session(
|
||||
account_id = account_id,
|
||||
refresh_token = refresh_token,
|
||||
access_token = access_token,
|
||||
data = {
|
||||
'refresh_token': refresh_token,
|
||||
'ip_address': ip_address,
|
||||
'created_at': str(now),
|
||||
'expires_at': str(now + timedelta(seconds = self.jwt_token_config.get('access_expiration_time')))
|
||||
},
|
||||
duration = self.jwt_token_config.get('access_expiration_time')
|
||||
)
|
||||
|
||||
if not short_session_response:
|
||||
self.logger.error(f"Could not create a short session for `{account_id}`")
|
||||
|
||||
raise ApplicationException(AccountErrorCode.GENERIC, AccountErrorMessage.GENERIC)
|
||||
|
||||
self.logger.debug(f"Short session created for `{account_id}`")
|
||||
|
||||
return True
|
||||
|
||||
def _schedule_task(self):
|
||||
pass
|
||||
|
||||
def _validate_parameters(self):
|
||||
pass
|
||||
|
||||
def _prepare_configs(self) -> None:
|
||||
"""
|
||||
Loads the configs.
|
||||
"""
|
||||
|
||||
self.session_config = Config('security/session')
|
||||
|
||||
self.jwt_token_config = Config('security/token').get('jwt_token')
|
||||
|
||||
def _prepare_modules(self) -> None:
|
||||
"""
|
||||
Initialize and set the instances.
|
||||
"""
|
||||
|
||||
self.data_memory = AccountSessionMemory(
|
||||
database = self.session_config.get('database').get('memory_database')
|
||||
)
|
|
@ -0,0 +1,120 @@
|
|||
from __future__ import annotations
|
||||
|
||||
from piracyshield_service.base import BaseService
|
||||
|
||||
from piracyshield_component.config import Config
|
||||
from piracyshield_component.utils.time import Time
|
||||
from piracyshield_component.exception import ApplicationException
|
||||
|
||||
from piracyshield_data_storage.account.session.memory import AccountSessionMemory, AccountSessionMemorySetException, AccountSessionMemoryGetException
|
||||
|
||||
from piracyshield_service.account.session.get_current_by_account import AccountSessionGetCurrentByAccountService
|
||||
from piracyshield_service.account.session.remove_long_session import AccountSessionRemoveLongSessionService
|
||||
from piracyshield_service.account.session.remove_short_session import AccountSessionRemoveShortSessionService
|
||||
|
||||
from piracyshield_service.security.blacklist.add_refresh_token import SecurityBlacklistAddRefreshTokenService
|
||||
from piracyshield_service.security.blacklist.add_access_token import SecurityBlacklistAddAccessTokenService
|
||||
|
||||
from dateutil.parser import parse
|
||||
|
||||
class AccountSessionDestroyCurrentSessionsService(BaseService):
|
||||
|
||||
"""
|
||||
Blacklists current sessions since we're logging out.
|
||||
"""
|
||||
|
||||
security_blacklist_add_access_token_service = None
|
||||
|
||||
security_blacklist_add_refresh_token_service = None
|
||||
|
||||
account_session_remove_short_session_service = None
|
||||
|
||||
account_session_remove_long_session_service = None
|
||||
|
||||
account_session_get_current_by_account_service = None
|
||||
|
||||
session_config = None
|
||||
|
||||
data_storage = None
|
||||
|
||||
def __init__(self):
|
||||
"""
|
||||
Inizialize logger and required modules.
|
||||
"""
|
||||
|
||||
super().__init__()
|
||||
|
||||
self._prepare_configs()
|
||||
|
||||
self._prepare_modules()
|
||||
|
||||
def execute(self, account_id: str, current_access_token: str) -> bool | Exception:
|
||||
long_session, short_sessions = self.account_session_get_current_by_account_service.execute(
|
||||
account_id = account_id,
|
||||
current_access_token = current_access_token
|
||||
)
|
||||
|
||||
now = Time.now()
|
||||
|
||||
long_token_blacklist_delay = parse(long_session.get('expires_at')) - now
|
||||
|
||||
long_token_blacklist_duration = round(long_token_blacklist_delay.total_seconds())
|
||||
|
||||
self.security_blacklist_add_refresh_token_service.execute(
|
||||
refresh_token = long_session.get('token'),
|
||||
duration = long_token_blacklist_duration
|
||||
)
|
||||
|
||||
self.account_session_remove_long_session_service.execute(
|
||||
account_id = account_id,
|
||||
refresh_token = long_session.get('token')
|
||||
)
|
||||
|
||||
for short_session in short_sessions:
|
||||
short_token_blacklist_delay = parse(short_session.get('expires_at')) - now
|
||||
|
||||
short_token_blacklist_duration = round(short_token_blacklist_delay.total_seconds())
|
||||
|
||||
self.security_blacklist_add_access_token_service.execute(
|
||||
access_token = short_session.get('token'),
|
||||
duration = short_token_blacklist_duration
|
||||
)
|
||||
|
||||
self.account_session_remove_short_session_service.execute(
|
||||
account_id = account_id,
|
||||
access_token = short_session.get('token')
|
||||
)
|
||||
|
||||
return True
|
||||
|
||||
def _schedule_task(self):
|
||||
pass
|
||||
|
||||
def _validate_parameters(self):
|
||||
pass
|
||||
|
||||
def _prepare_configs(self) -> None:
|
||||
"""
|
||||
Loads the configs.
|
||||
"""
|
||||
|
||||
self.session_config = Config('security/session')
|
||||
|
||||
def _prepare_modules(self) -> None:
|
||||
"""
|
||||
Initialize and set the instances.
|
||||
"""
|
||||
|
||||
self.data_memory = AccountSessionMemory(
|
||||
database = self.session_config.get('database').get('memory_database')
|
||||
)
|
||||
|
||||
self.account_session_get_current_by_account_service = AccountSessionGetCurrentByAccountService()
|
||||
|
||||
self.account_session_remove_long_session_service = AccountSessionRemoveLongSessionService()
|
||||
|
||||
self.account_session_remove_short_session_service = AccountSessionRemoveShortSessionService()
|
||||
|
||||
self.security_blacklist_add_refresh_token_service = SecurityBlacklistAddRefreshTokenService()
|
||||
|
||||
self.security_blacklist_add_access_token_service = SecurityBlacklistAddAccessTokenService()
|
|
@ -0,0 +1,56 @@
|
|||
from __future__ import annotations
|
||||
|
||||
from piracyshield_service.base import BaseService
|
||||
|
||||
from piracyshield_component.config import Config
|
||||
from piracyshield_component.exception import ApplicationException
|
||||
|
||||
from piracyshield_data_storage.account.session.memory import AccountSessionMemory, AccountSessionMemorySetException, AccountSessionMemoryGetException
|
||||
|
||||
class AccountSessionFindLongSessionService(BaseService):
|
||||
|
||||
"""
|
||||
Searches for an specific long session.
|
||||
"""
|
||||
|
||||
session_config = None
|
||||
|
||||
data_storage = None
|
||||
|
||||
def __init__(self):
|
||||
"""
|
||||
Inizialize logger and required modules.
|
||||
"""
|
||||
|
||||
super().__init__()
|
||||
|
||||
self._prepare_configs()
|
||||
|
||||
self._prepare_modules()
|
||||
|
||||
def execute(self, refresh_token: str) -> bool | Exception:
|
||||
return self.data_memory.find_long_session(
|
||||
refresh_token = refresh_token
|
||||
)
|
||||
|
||||
def _schedule_task(self):
|
||||
pass
|
||||
|
||||
def _validate_parameters(self):
|
||||
pass
|
||||
|
||||
def _prepare_configs(self) -> None:
|
||||
"""
|
||||
Loads the configs.
|
||||
"""
|
||||
|
||||
self.session_config = Config('security/session')
|
||||
|
||||
def _prepare_modules(self) -> None:
|
||||
"""
|
||||
Initialize and set the instances.
|
||||
"""
|
||||
|
||||
self.data_memory = AccountSessionMemory(
|
||||
database = self.session_config.get('database').get('memory_database')
|
||||
)
|
|
@ -0,0 +1,96 @@
|
|||
from __future__ import annotations
|
||||
|
||||
from piracyshield_service.base import BaseService
|
||||
|
||||
from piracyshield_component.config import Config
|
||||
from piracyshield_component.exception import ApplicationException
|
||||
|
||||
from piracyshield_data_storage.account.session.memory import AccountSessionMemory, AccountSessionMemorySetException, AccountSessionMemoryGetException
|
||||
|
||||
class AccountSessionGetAllByAccountOrderedService(BaseService):
|
||||
|
||||
"""
|
||||
Retrieves all active sessions ordering them.
|
||||
"""
|
||||
|
||||
session_config = None
|
||||
|
||||
data_storage = None
|
||||
|
||||
def __init__(self):
|
||||
"""
|
||||
Inizialize logger and required modules.
|
||||
"""
|
||||
|
||||
super().__init__()
|
||||
|
||||
self._prepare_configs()
|
||||
|
||||
self._prepare_modules()
|
||||
|
||||
def execute(self, account_id: str, current_access_token: str) -> bool | Exception:
|
||||
# NOTE: have some optimizations in all of this.
|
||||
|
||||
sessions = self.data_memory.get_all_by_account(
|
||||
account_id = account_id
|
||||
)
|
||||
|
||||
long_sessions = []
|
||||
short_sessions = []
|
||||
|
||||
for entry in sessions:
|
||||
(_, _, genre, token) = entry.split(':')
|
||||
|
||||
session = {
|
||||
'metadata': self.data_memory.get_session(entry)
|
||||
}
|
||||
|
||||
if genre == 'long':
|
||||
session['long_session'] = token
|
||||
|
||||
long_sessions.append(session)
|
||||
|
||||
elif genre == 'short':
|
||||
session['short_session'] = token
|
||||
|
||||
if token in current_access_token:
|
||||
session['is_current'] = True
|
||||
|
||||
short_sessions.append(session)
|
||||
|
||||
for long_session in long_sessions:
|
||||
long_session['short_sessions'] = []
|
||||
|
||||
for short_session in short_sessions:
|
||||
if short_session.get('metadata').get('refresh_token') == long_session.get('long_session'):
|
||||
long_session['short_sessions'].append(short_session)
|
||||
|
||||
# if it's the currently used short session we can safely say that this is its long sessions
|
||||
if short_session.get('is_current') == True:
|
||||
long_session['is_current'] = True
|
||||
|
||||
return {
|
||||
'long_sessions': long_sessions
|
||||
}
|
||||
|
||||
def _schedule_task(self):
|
||||
pass
|
||||
|
||||
def _validate_parameters(self):
|
||||
pass
|
||||
|
||||
def _prepare_configs(self) -> None:
|
||||
"""
|
||||
Loads the configs.
|
||||
"""
|
||||
|
||||
self.session_config = Config('security/session')
|
||||
|
||||
def _prepare_modules(self) -> None:
|
||||
"""
|
||||
Initialize and set the instances.
|
||||
"""
|
||||
|
||||
self.data_memory = AccountSessionMemory(
|
||||
database = self.session_config.get('database').get('memory_database')
|
||||
)
|
|
@ -0,0 +1,97 @@
|
|||
from __future__ import annotations
|
||||
|
||||
from piracyshield_service.base import BaseService
|
||||
|
||||
from piracyshield_component.config import Config
|
||||
from piracyshield_component.exception import ApplicationException
|
||||
|
||||
from piracyshield_data_storage.account.session.memory import AccountSessionMemory, AccountSessionMemorySetException, AccountSessionMemoryGetException
|
||||
|
||||
class AccountSessionGetCurrentByAccountService(BaseService):
|
||||
|
||||
"""
|
||||
Retrieves all the current sessions only.
|
||||
"""
|
||||
|
||||
session_config = None
|
||||
|
||||
data_storage = None
|
||||
|
||||
def __init__(self):
|
||||
"""
|
||||
Inizialize logger and required modules.
|
||||
"""
|
||||
|
||||
super().__init__()
|
||||
|
||||
self._prepare_configs()
|
||||
|
||||
self._prepare_modules()
|
||||
|
||||
def execute(self, account_id: str, current_access_token: str) -> bool | Exception:
|
||||
# NOTE: have some optimizations in all of this.
|
||||
|
||||
sessions = self.data_memory.get_all_short_by_account(
|
||||
account_id = account_id
|
||||
)
|
||||
|
||||
long_session = None
|
||||
|
||||
short_sessions = []
|
||||
|
||||
# find the first short session to get back the long session
|
||||
for entry in sessions:
|
||||
(_, _, genre, token) = entry.split(':')
|
||||
|
||||
# we found the current session
|
||||
if token in current_access_token:
|
||||
session = self.data_memory.get_session(entry)
|
||||
|
||||
session['token'] = token
|
||||
|
||||
short_sessions.append(session)
|
||||
|
||||
# TODO: need to deal with this in the storage.
|
||||
# let's save the long session as well
|
||||
long_session = self.data_memory.get_session(f'session:{account_id}:long:{session.get('refresh_token')}')
|
||||
|
||||
long_session['token'] = session.get('refresh_token')
|
||||
|
||||
# avoid reappending the same session when we redo all of this
|
||||
sessions.remove(entry)
|
||||
|
||||
break
|
||||
|
||||
for entry in sessions:
|
||||
(_, _, genre, token) = entry.split(':')
|
||||
|
||||
session = self.data_memory.get_session(entry)
|
||||
|
||||
if session.get('refresh_token') == long_session.get('token'):
|
||||
session['token'] = token
|
||||
|
||||
short_sessions.append(session)
|
||||
|
||||
return (long_session, short_sessions)
|
||||
|
||||
def _schedule_task(self):
|
||||
pass
|
||||
|
||||
def _validate_parameters(self):
|
||||
pass
|
||||
|
||||
def _prepare_configs(self) -> None:
|
||||
"""
|
||||
Loads the configs.
|
||||
"""
|
||||
|
||||
self.session_config = Config('security/session')
|
||||
|
||||
def _prepare_modules(self) -> None:
|
||||
"""
|
||||
Initialize and set the instances.
|
||||
"""
|
||||
|
||||
self.data_memory = AccountSessionMemory(
|
||||
database = self.session_config.get('database').get('memory_database')
|
||||
)
|
|
@ -0,0 +1,57 @@
|
|||
from __future__ import annotations
|
||||
|
||||
from piracyshield_service.base import BaseService
|
||||
|
||||
from piracyshield_component.config import Config
|
||||
from piracyshield_component.exception import ApplicationException
|
||||
|
||||
from piracyshield_data_storage.account.session.memory import AccountSessionMemory, AccountSessionMemorySetException, AccountSessionMemoryGetException
|
||||
|
||||
class AccountSessionRemoveLongSessionService(BaseService):
|
||||
|
||||
"""
|
||||
Removes a long session.
|
||||
"""
|
||||
|
||||
session_config = None
|
||||
|
||||
data_storage = None
|
||||
|
||||
def __init__(self):
|
||||
"""
|
||||
Inizialize logger and required modules.
|
||||
"""
|
||||
|
||||
super().__init__()
|
||||
|
||||
self._prepare_configs()
|
||||
|
||||
self._prepare_modules()
|
||||
|
||||
def execute(self, account_id: str, refresh_token: str) -> bool | Exception:
|
||||
return self.data_memory.remove_long_session(
|
||||
account_id = account_id,
|
||||
refresh_token = refresh_token
|
||||
)
|
||||
|
||||
def _schedule_task(self):
|
||||
pass
|
||||
|
||||
def _validate_parameters(self):
|
||||
pass
|
||||
|
||||
def _prepare_configs(self) -> None:
|
||||
"""
|
||||
Loads the configs.
|
||||
"""
|
||||
|
||||
self.session_config = Config('security/session')
|
||||
|
||||
def _prepare_modules(self) -> None:
|
||||
"""
|
||||
Initialize and set the instances.
|
||||
"""
|
||||
|
||||
self.data_memory = AccountSessionMemory(
|
||||
database = self.session_config.get('database').get('memory_database')
|
||||
)
|
|
@ -0,0 +1,57 @@
|
|||
from __future__ import annotations
|
||||
|
||||
from piracyshield_service.base import BaseService
|
||||
|
||||
from piracyshield_component.config import Config
|
||||
from piracyshield_component.exception import ApplicationException
|
||||
|
||||
from piracyshield_data_storage.account.session.memory import AccountSessionMemory, AccountSessionMemorySetException, AccountSessionMemoryGetException
|
||||
|
||||
class AccountSessionRemoveShortSessionService(BaseService):
|
||||
|
||||
"""
|
||||
Removes a short session.
|
||||
"""
|
||||
|
||||
session_config = None
|
||||
|
||||
data_storage = None
|
||||
|
||||
def __init__(self):
|
||||
"""
|
||||
Inizialize logger and required modules.
|
||||
"""
|
||||
|
||||
super().__init__()
|
||||
|
||||
self._prepare_configs()
|
||||
|
||||
self._prepare_modules()
|
||||
|
||||
def execute(self, account_id: str, access_token: str) -> bool | Exception:
|
||||
return self.data_memory.remove_short_session(
|
||||
account_id = account_id,
|
||||
access_token = access_token
|
||||
)
|
||||
|
||||
def _schedule_task(self):
|
||||
pass
|
||||
|
||||
def _validate_parameters(self):
|
||||
pass
|
||||
|
||||
def _prepare_configs(self) -> None:
|
||||
"""
|
||||
Loads the configs.
|
||||
"""
|
||||
|
||||
self.session_config = Config('security/session')
|
||||
|
||||
def _prepare_modules(self) -> None:
|
||||
"""
|
||||
Initialize and set the instances.
|
||||
"""
|
||||
|
||||
self.data_memory = AccountSessionMemory(
|
||||
database = self.session_config.get('database').get('memory_database')
|
||||
)
|
|
@ -11,6 +11,10 @@ from piracyshield_data_model.authentication.model import AuthenticationModel, Au
|
|||
from piracyshield_data_storage.authentication.storage import AuthenticationStorage, AuthenticationStorageGetException
|
||||
|
||||
from piracyshield_service.authentication.get import AuthenticationGetService
|
||||
from piracyshield_service.authentication.generate_access_token import AuthenticationGenerateAccessTokenService
|
||||
from piracyshield_service.authentication.generate_refresh_token import AuthenticationGenerateRefreshTokenService
|
||||
|
||||
from piracyshield_service.account.session.create import AccountSessionCreateService
|
||||
|
||||
from piracyshield_service.security.anti_brute_force import SecurityAntiBruteForceService
|
||||
|
||||
|
@ -22,6 +26,12 @@ class AuthenticationAuthenticateService(BaseService):
|
|||
Credentials based authentication.
|
||||
"""
|
||||
|
||||
authentication_generate_access_token_service = None
|
||||
|
||||
authentication_generate_refresh_token_service = None
|
||||
|
||||
account_session_create_service = None
|
||||
|
||||
security_anti_brute_force_service = None
|
||||
|
||||
authentication_get_service = None
|
||||
|
@ -34,8 +44,6 @@ class AuthenticationAuthenticateService(BaseService):
|
|||
|
||||
hasher_config = None
|
||||
|
||||
login_config = None
|
||||
|
||||
def __init__(self):
|
||||
"""
|
||||
Inizialize logger and required modules.
|
||||
|
@ -73,7 +81,22 @@ class AuthenticationAuthenticateService(BaseService):
|
|||
|
||||
self.logger.debug(f"Account `{account.get('email')}` correctly authenticated.")
|
||||
|
||||
return self._build_payload(account)
|
||||
# get the payload to encode
|
||||
payload = self._build_payload(account)
|
||||
|
||||
# generate token pairs
|
||||
refresh_token = self.authentication_generate_refresh_token_service.execute(payload)
|
||||
access_token = self.authentication_generate_access_token_service.execute(payload)
|
||||
|
||||
# create a new session for this account
|
||||
self.account_session_create_service.execute(
|
||||
account_id = account.get('account_id'),
|
||||
refresh_token = refresh_token,
|
||||
access_token = access_token,
|
||||
ip_address = ip_address
|
||||
)
|
||||
|
||||
return (access_token, refresh_token)
|
||||
|
||||
def _verify_password(self, password: str, hashed_password: str) -> bool:
|
||||
"""
|
||||
|
@ -127,10 +150,10 @@ class AuthenticationAuthenticateService(BaseService):
|
|||
Loads the configs.
|
||||
"""
|
||||
|
||||
self.security_anti_brute_force_config = Config('security/anti_brute_force').get('general')
|
||||
|
||||
self.hasher_config = Config('security/token').get('hasher')
|
||||
|
||||
self.security_anti_brute_force_config = Config('security/anti_brute_force').get('general')
|
||||
|
||||
def _prepare_modules(self) -> None:
|
||||
"""
|
||||
Initialize and set the instances.
|
||||
|
@ -138,6 +161,8 @@ class AuthenticationAuthenticateService(BaseService):
|
|||
|
||||
self.data_model = AuthenticationModel
|
||||
|
||||
self.data_storage = AuthenticationStorage()
|
||||
|
||||
self.hasher = Hasher(
|
||||
time_cost = self.hasher_config.get('time_cost'),
|
||||
memory_cost = self.hasher_config.get('memory_cost'),
|
||||
|
@ -146,8 +171,12 @@ class AuthenticationAuthenticateService(BaseService):
|
|||
salt_length = self.hasher_config.get('salt_length')
|
||||
)
|
||||
|
||||
self.data_storage = AuthenticationStorage()
|
||||
|
||||
self.authentication_get_service = AuthenticationGetService()
|
||||
|
||||
self.authentication_generate_access_token_service = AuthenticationGenerateAccessTokenService()
|
||||
|
||||
self.authentication_generate_refresh_token_service = AuthenticationGenerateRefreshTokenService()
|
||||
|
||||
self.account_session_create_service = AccountSessionCreateService()
|
||||
|
||||
self.security_anti_brute_force_service = SecurityAntiBruteForceService()
|
||||
|
|
|
@ -16,7 +16,7 @@ class AuthenticationGenerateAccessTokenService(BaseService):
|
|||
|
||||
token = None
|
||||
|
||||
jwt_config = None
|
||||
jwt_token_config = None
|
||||
|
||||
def __init__(self):
|
||||
"""
|
||||
|
@ -49,7 +49,7 @@ class AuthenticationGenerateAccessTokenService(BaseService):
|
|||
Loads the configs.
|
||||
"""
|
||||
|
||||
self.jwt_config = Config('security/token').get('jwt_token')
|
||||
self.jwt_token_config = Config('security/token').get('jwt_token')
|
||||
|
||||
def _prepare_modules(self) -> None:
|
||||
"""
|
||||
|
@ -57,9 +57,9 @@ class AuthenticationGenerateAccessTokenService(BaseService):
|
|||
"""
|
||||
|
||||
self.token = JWTToken(
|
||||
access_secret_key = self.jwt_config.get('access_secret_key'),
|
||||
refresh_secret_key = self.jwt_config.get('refresh_secret_key'),
|
||||
access_expiration_time = self.jwt_config.get('access_expiration_time'),
|
||||
refresh_expiration_time = self.jwt_config.get('refresh_expiration_time'),
|
||||
algorithm = self.jwt_config.get('algorithm')
|
||||
access_secret_key = self.jwt_token_config.get('access_secret_key'),
|
||||
refresh_secret_key = self.jwt_token_config.get('refresh_secret_key'),
|
||||
access_expiration_time = self.jwt_token_config.get('access_expiration_time'),
|
||||
refresh_expiration_time = self.jwt_token_config.get('refresh_expiration_time'),
|
||||
algorithm = self.jwt_token_config.get('algorithm')
|
||||
)
|
||||
|
|
|
@ -16,7 +16,7 @@ class AuthenticationGenerateRefreshTokenService(BaseService):
|
|||
|
||||
token = None
|
||||
|
||||
jwt_config = None
|
||||
jwt_token_config = None
|
||||
|
||||
def __init__(self):
|
||||
"""
|
||||
|
@ -49,7 +49,7 @@ class AuthenticationGenerateRefreshTokenService(BaseService):
|
|||
Loads the configs.
|
||||
"""
|
||||
|
||||
self.jwt_config = Config('security/token').get('jwt_token')
|
||||
self.jwt_token_config = Config('security/token').get('jwt_token')
|
||||
|
||||
def _prepare_modules(self) -> None:
|
||||
"""
|
||||
|
@ -57,9 +57,9 @@ class AuthenticationGenerateRefreshTokenService(BaseService):
|
|||
"""
|
||||
|
||||
self.token = JWTToken(
|
||||
access_secret_key = self.jwt_config.get('access_secret_key'),
|
||||
refresh_secret_key = self.jwt_config.get('refresh_secret_key'),
|
||||
access_expiration_time = self.jwt_config.get('access_expiration_time'),
|
||||
refresh_expiration_time = self.jwt_config.get('refresh_expiration_time'),
|
||||
algorithm = self.jwt_config.get('algorithm')
|
||||
access_secret_key = self.jwt_token_config.get('access_secret_key'),
|
||||
refresh_secret_key = self.jwt_token_config.get('refresh_secret_key'),
|
||||
access_expiration_time = self.jwt_token_config.get('access_expiration_time'),
|
||||
refresh_expiration_time = self.jwt_token_config.get('refresh_expiration_time'),
|
||||
algorithm = self.jwt_token_config.get('algorithm')
|
||||
)
|
||||
|
|
104
src/piracyshield_service/authentication/refresh_access_token.py
Normal file
104
src/piracyshield_service/authentication/refresh_access_token.py
Normal file
|
@ -0,0 +1,104 @@
|
|||
from __future__ import annotations
|
||||
|
||||
from piracyshield_service.base import BaseService
|
||||
|
||||
from piracyshield_component.config import Config
|
||||
from piracyshield_component.exception import ApplicationException
|
||||
|
||||
from piracyshield_service.authentication.verify_refresh_token import AuthenticationVerifyRefreshTokenService
|
||||
from piracyshield_service.authentication.generate_access_token import AuthenticationGenerateAccessTokenService
|
||||
|
||||
from piracyshield_service.account.session.find_long_session import AccountSessionFindLongSessionService
|
||||
from piracyshield_service.account.session.create_short_session import AccountSessionCreateShortSessionService
|
||||
|
||||
from piracyshield_service.security.anti_brute_force import SecurityAntiBruteForceService
|
||||
|
||||
from piracyshield_service.authentication.errors import AuthenticationErrorCode, AuthenticationErrorMessage
|
||||
|
||||
class AuthenticationRefreshAccessTokenService(BaseService):
|
||||
|
||||
"""
|
||||
Refreshes the access token provided a valid and active refresh token.
|
||||
"""
|
||||
|
||||
authentication_generate_access_token_service = None
|
||||
|
||||
authentication_verify_refresh_token_service = None
|
||||
|
||||
account_session_find_long_session_service = None
|
||||
|
||||
account_session_create_short_session_service = None
|
||||
|
||||
jwt_token_config = None
|
||||
|
||||
def __init__(self):
|
||||
"""
|
||||
Inizialize logger and required modules.
|
||||
"""
|
||||
|
||||
super().__init__()
|
||||
|
||||
self._prepare_configs()
|
||||
|
||||
self._prepare_modules()
|
||||
|
||||
def execute(self, refresh_token: str, ip_address: str) -> dict | Exception:
|
||||
# TODO: verify if blacklisted.
|
||||
|
||||
# verify the token and unwrap the payload
|
||||
payload = self.authentication_verify_refresh_token_service.execute(
|
||||
token = refresh_token
|
||||
)
|
||||
|
||||
# retrieve the long session data so we can check out which account identifier is assigned to this new token
|
||||
long_session = self.account_session_find_long_session_service.execute(
|
||||
refresh_token = refresh_token
|
||||
)
|
||||
|
||||
account_id = None
|
||||
|
||||
if long_session:
|
||||
(_, account_id, _, _) = long_session.split(':')
|
||||
|
||||
else:
|
||||
self.logger.error(f"Could not find a long session for this refresh token `{refresh_token}`")
|
||||
|
||||
raise ApplicationException(AuthenticationErrorCode.GENERIC, AuthenticationErrorMessage.GENERIC)
|
||||
|
||||
access_token = self.authentication_generate_access_token_service.execute(payload)
|
||||
|
||||
# create a new session for this user
|
||||
self.account_session_create_short_session_service.execute(
|
||||
refresh_token = refresh_token,
|
||||
access_token = access_token,
|
||||
account_id = account_id,
|
||||
ip_address = ip_address
|
||||
)
|
||||
|
||||
return access_token
|
||||
|
||||
def _schedule_task(self):
|
||||
pass
|
||||
|
||||
def _validate_parameters(self):
|
||||
pass
|
||||
|
||||
def _prepare_configs(self) -> None:
|
||||
"""
|
||||
Loads the configs.
|
||||
"""
|
||||
|
||||
self.jwt_token_config = Config('security/token').get('jwt_token')
|
||||
|
||||
def _prepare_modules(self) -> None:
|
||||
"""
|
||||
Initialize and set the instances.
|
||||
"""
|
||||
|
||||
self.authentication_verify_refresh_token_service = AuthenticationVerifyRefreshTokenService()
|
||||
|
||||
self.authentication_generate_access_token_service = AuthenticationGenerateAccessTokenService()
|
||||
|
||||
self.account_session_find_long_session_service = AccountSessionFindLongSessionService()
|
||||
|
||||
self.account_session_create_short_session_service = AccountSessionCreateShortSessionService()
|
|
@ -5,14 +5,14 @@ from piracyshield_service.base import BaseService
|
|||
from piracyshield_component.config import Config
|
||||
from piracyshield_component.exception import ApplicationException
|
||||
|
||||
from piracyshield_data_storage.security.memory import SecurityMemory, SecurityMemorySetException, SecurityMemoryGetException
|
||||
from piracyshield_data_storage.security.blacklist.memory import SecurityBlacklistMemory, SecurityBlacklistMemorySetException, SecurityBlacklistMemoryGetException
|
||||
|
||||
from piracyshield_service.security.errors import SecurityErrorCode, SecurityErrorMessage
|
||||
|
||||
class SecurityBlacklistCreateService(BaseService):
|
||||
class SecurityBlacklistAddAccessTokenService(BaseService):
|
||||
|
||||
"""
|
||||
Blacklists an item.
|
||||
Blacklists an access token.
|
||||
"""
|
||||
|
||||
blacklist_config = None
|
||||
|
@ -30,14 +30,14 @@ class SecurityBlacklistCreateService(BaseService):
|
|||
|
||||
self._prepare_modules()
|
||||
|
||||
def execute(self, item: str, duration: int) -> bool | Exception:
|
||||
response = self.data_memory.add_to_blacklist(
|
||||
item = item,
|
||||
def execute(self, access_token: str, duration: int) -> bool | Exception:
|
||||
response = self.data_memory.add_access_token(
|
||||
access_token = access_token,
|
||||
duration = duration
|
||||
)
|
||||
|
||||
if response == True:
|
||||
self.logger.warning(f"Blacklist item `{item}` has been created for {duration} seconds")
|
||||
self.logger.warning(f"New access token has been blacklisted for {duration} seconds")
|
||||
|
||||
return True
|
||||
|
||||
|
@ -61,6 +61,6 @@ class SecurityBlacklistCreateService(BaseService):
|
|||
Initialize and set the instances.
|
||||
"""
|
||||
|
||||
self.data_memory = SecurityMemory(
|
||||
self.data_memory = SecurityBlacklistMemory(
|
||||
database = self.blacklist_config.get('database').get('memory_database')
|
||||
)
|
|
@ -0,0 +1,66 @@
|
|||
from __future__ import annotations
|
||||
|
||||
from piracyshield_service.base import BaseService
|
||||
|
||||
from piracyshield_component.config import Config
|
||||
from piracyshield_component.exception import ApplicationException
|
||||
|
||||
from piracyshield_data_storage.security.blacklist.memory import SecurityBlacklistMemory, SecurityBlacklistMemorySetException, SecurityBlacklistMemoryGetException
|
||||
|
||||
from piracyshield_service.security.errors import SecurityErrorCode, SecurityErrorMessage
|
||||
|
||||
class SecurityBlacklistAddRefreshTokenService(BaseService):
|
||||
|
||||
"""
|
||||
Blacklists a refresh token.
|
||||
"""
|
||||
|
||||
blacklist_config = None
|
||||
|
||||
data_storage = None
|
||||
|
||||
def __init__(self):
|
||||
"""
|
||||
Inizialize logger and required modules.
|
||||
"""
|
||||
|
||||
super().__init__()
|
||||
|
||||
self._prepare_configs()
|
||||
|
||||
self._prepare_modules()
|
||||
|
||||
def execute(self, refresh_token: str, duration: int) -> bool | Exception:
|
||||
response = self.data_memory.add_refresh_token(
|
||||
refresh_token = refresh_token,
|
||||
duration = duration
|
||||
)
|
||||
|
||||
if response == True:
|
||||
self.logger.warning(f"New refresh token has been blacklisted for {duration} seconds")
|
||||
|
||||
return True
|
||||
|
||||
return response
|
||||
|
||||
def _schedule_task(self):
|
||||
pass
|
||||
|
||||
def _validate_parameters(self):
|
||||
pass
|
||||
|
||||
def _prepare_configs(self) -> None:
|
||||
"""
|
||||
Loads the configs.
|
||||
"""
|
||||
|
||||
self.blacklist_config = Config('security/blacklist')
|
||||
|
||||
def _prepare_modules(self) -> None:
|
||||
"""
|
||||
Initialize and set the instances.
|
||||
"""
|
||||
|
||||
self.data_memory = SecurityBlacklistMemory(
|
||||
database = self.blacklist_config.get('database').get('memory_database')
|
||||
)
|
|
@ -0,0 +1,58 @@
|
|||
from __future__ import annotations
|
||||
|
||||
from piracyshield_service.base import BaseService
|
||||
|
||||
from piracyshield_component.config import Config
|
||||
from piracyshield_component.exception import ApplicationException
|
||||
|
||||
from piracyshield_data_storage.security.blacklist.memory import SecurityBlacklistMemory, SecurityBlacklistMemorySetException, SecurityBlacklistMemoryGetException
|
||||
|
||||
from piracyshield_service.security.errors import SecurityErrorCode, SecurityErrorMessage
|
||||
|
||||
class SecurityBlacklistExistsByAccessTokenService(BaseService):
|
||||
|
||||
"""
|
||||
Checks if an access token has been blacklisted.
|
||||
"""
|
||||
|
||||
blacklist_config = None
|
||||
|
||||
data_storage = None
|
||||
|
||||
def __init__(self):
|
||||
"""
|
||||
Inizialize logger and required modules.
|
||||
"""
|
||||
|
||||
super().__init__()
|
||||
|
||||
self._prepare_configs()
|
||||
|
||||
self._prepare_modules()
|
||||
|
||||
def execute(self, access_token: str) -> bool | Exception:
|
||||
return self.data_memory.exists_by_access_token(
|
||||
access_token = access_token
|
||||
)
|
||||
|
||||
def _schedule_task(self):
|
||||
pass
|
||||
|
||||
def _validate_parameters(self):
|
||||
pass
|
||||
|
||||
def _prepare_configs(self) -> None:
|
||||
"""
|
||||
Loads the configs.
|
||||
"""
|
||||
|
||||
self.blacklist_config = Config('security/blacklist')
|
||||
|
||||
def _prepare_modules(self) -> None:
|
||||
"""
|
||||
Initialize and set the instances.
|
||||
"""
|
||||
|
||||
self.data_memory = SecurityBlacklistMemory(
|
||||
database = self.blacklist_config.get('database').get('memory_database')
|
||||
)
|
|
@ -0,0 +1,58 @@
|
|||
from __future__ import annotations
|
||||
|
||||
from piracyshield_service.base import BaseService
|
||||
|
||||
from piracyshield_component.config import Config
|
||||
from piracyshield_component.exception import ApplicationException
|
||||
|
||||
from piracyshield_data_storage.security.blacklist.memory import SecurityBlacklistMemory, SecurityBlacklistMemorySetException, SecurityBlacklistMemoryGetException
|
||||
|
||||
from piracyshield_service.security.errors import SecurityErrorCode, SecurityErrorMessage
|
||||
|
||||
class SecurityBlacklistExistsByRefreshTokenService(BaseService):
|
||||
|
||||
"""
|
||||
Checks if a refresh token has been blacklisted.
|
||||
"""
|
||||
|
||||
blacklist_config = None
|
||||
|
||||
data_storage = None
|
||||
|
||||
def __init__(self):
|
||||
"""
|
||||
Inizialize logger and required modules.
|
||||
"""
|
||||
|
||||
super().__init__()
|
||||
|
||||
self._prepare_configs()
|
||||
|
||||
self._prepare_modules()
|
||||
|
||||
def execute(self, refresh_token: str) -> bool | Exception:
|
||||
return self.data_memory.exists_by_refresh_token(
|
||||
refresh_token = refresh_token
|
||||
)
|
||||
|
||||
def _schedule_task(self):
|
||||
pass
|
||||
|
||||
def _validate_parameters(self):
|
||||
pass
|
||||
|
||||
def _prepare_configs(self) -> None:
|
||||
"""
|
||||
Loads the configs.
|
||||
"""
|
||||
|
||||
self.blacklist_config = Config('security/blacklist')
|
||||
|
||||
def _prepare_modules(self) -> None:
|
||||
"""
|
||||
Initialize and set the instances.
|
||||
"""
|
||||
|
||||
self.data_memory = SecurityBlacklistMemory(
|
||||
database = self.blacklist_config.get('database').get('memory_database')
|
||||
)
|
1
src/piracyshield_service/security/session/__init__.py
Normal file
1
src/piracyshield_service/security/session/__init__.py
Normal file
|
@ -0,0 +1 @@
|
|||
|
|
@ -127,8 +127,6 @@ class TicketRelationEstablishService(BaseService):
|
|||
value = value
|
||||
)
|
||||
|
||||
print(" r -> ", found_tickets)
|
||||
|
||||
# no ticket item found
|
||||
if not len(found_tickets):
|
||||
return False
|
||||
|
@ -137,7 +135,6 @@ class TicketRelationEstablishService(BaseService):
|
|||
if len(found_tickets):
|
||||
# but let's search for a ticket error in this case
|
||||
for ticket_blocking in found_tickets:
|
||||
print(" tb -> ", ticket_blocking)
|
||||
ticket_errors = self.ticket_error_get_by_ticket_service.execute(
|
||||
ticket_blocking.get('ticket_id')
|
||||
)
|
||||
|
@ -145,11 +142,8 @@ class TicketRelationEstablishService(BaseService):
|
|||
# found one, let's search for our item
|
||||
if len(ticket_errors):
|
||||
for ticket_error_response in ticket_errors:
|
||||
print(ticket_error_response)
|
||||
print(ticket_error_response.get(genre))
|
||||
|
||||
# found the item, so we don't have any duplicate
|
||||
if value in ticket_error_response.get(genre):
|
||||
if genre in ticket_error_response and ticket_error_response.get(genre) and value in ticket_error_response.get(genre):
|
||||
return False
|
||||
|
||||
return True
|
||||
|
|
Loading…
Reference in a new issue