-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
22 changed files
with
682 additions
and
1 deletion.
There are no files selected for viewing
Empty file.
23 changes: 23 additions & 0 deletions
23
cumulus_lambda_functions/lib/authorization/uds_authorizer_abstract.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
from abc import ABC, abstractmethod | ||
|
||
|
||
class UDSAuthorizorAbstract(ABC): | ||
@abstractmethod | ||
def add_authorized_group(self, action: [str], project: str, venue: str, ldap_group_name: str): | ||
return | ||
|
||
@abstractmethod | ||
def delete_authorized_group(self, project: str, venue: str, ldap_group_name: str): | ||
return | ||
|
||
@abstractmethod | ||
def list_authorized_groups_for(self, project: str, venue: str): | ||
return | ||
|
||
@abstractmethod | ||
def update_authorized_group(self, action: [str], project: str, venue: str, ldap_group_name: str): | ||
return | ||
|
||
@abstractmethod | ||
def get_authorized_tenant(self, username: str, action: str) -> list: | ||
return [] |
114 changes: 114 additions & 0 deletions
114
cumulus_lambda_functions/lib/authorization/uds_authorizer_es_identity_pool.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
import logging | ||
import os | ||
|
||
from cumulus_lambda_functions.lib.authorization.uds_authorizer_abstract import UDSAuthorizorAbstract | ||
from cumulus_lambda_functions.lib.aws.aws_cognito import AwsCognito | ||
from cumulus_lambda_functions.lib.aws.es_abstract import ESAbstract | ||
from cumulus_lambda_functions.lib.aws.es_factory import ESFactory | ||
from cumulus_lambda_functions.lib.uds_db.db_constants import DBConstants | ||
|
||
LOGGER = logging.getLogger(__name__) | ||
|
||
|
||
class UDSAuthorizorEsIdentityPool(UDSAuthorizorAbstract): | ||
|
||
def __init__(self, user_pool_id: str) -> None: | ||
super().__init__() | ||
es_url = os.getenv('ES_URL') # TODO validation | ||
self.__authorization_index = os.getenv('AUTHORIZATION_INDEX') # LDAP_Group_Permission | ||
es_port = int(os.getenv('ES_PORT', '443')) | ||
self.__cognito = AwsCognito(user_pool_id) | ||
self.__es: ESAbstract = ESFactory().get_instance('AWS', | ||
index=self.__authorization_index, | ||
base_url=es_url, | ||
port=es_port) | ||
|
||
def add_authorized_group(self, action: [str], project: str, venue: str, ldap_group_name: str): | ||
self.__es.index_one({ | ||
DBConstants.action_key: action, | ||
DBConstants.project: project, | ||
DBConstants.project_venue: venue, | ||
DBConstants.authorized_group_name_key: ldap_group_name, | ||
}, f'{project}__{venue}__{ldap_group_name}', self.__authorization_index) | ||
return | ||
|
||
def delete_authorized_group(self, project: str, venue: str, ldap_group_name: str): | ||
self.__es.delete_by_query({ | ||
'query': { | ||
'bool': { | ||
'must': [ | ||
{'term': {DBConstants.project: project}}, | ||
{'term': {DBConstants.project_venue: venue}}, | ||
{'term': {DBConstants.authorized_group_name_key: ldap_group_name}}, | ||
] | ||
} | ||
} | ||
}) | ||
return | ||
|
||
def list_authorized_groups_for(self, project: str, venue: str): | ||
result = self.__es.query_pages({ | ||
'query': { | ||
'bool': { | ||
'must': [ | ||
{'term': {DBConstants.project: project}}, | ||
{'term': {DBConstants.project_venue: venue}}, | ||
] | ||
} | ||
}, | ||
'sort': [ | ||
{DBConstants.project: {'order': 'asc'}}, | ||
{DBConstants.project_venue: {'order': 'asc'}}, | ||
{DBConstants.authorized_group_name_key: {'order': 'asc'}}, | ||
] | ||
}) | ||
result = [k['_source'] for k in result['hits']['hits']] | ||
return result | ||
|
||
def update_authorized_group(self, action: [str], project: str, venue: str, ldap_group_name: str): | ||
self.__es.update_one({ | ||
DBConstants.action_key: action, | ||
DBConstants.project: project, | ||
DBConstants.project_venue: venue, | ||
DBConstants.authorized_group_name_key: ldap_group_name, | ||
}, f'{project}__{venue}__{ldap_group_name}', self.__authorization_index) | ||
return | ||
|
||
def get_authorized_tenant(self, username: str, action: str) -> list: | ||
belonged_groups = set(self.__cognito.get_groups(username)) | ||
|
||
authorized_groups = self.__es.query({ | ||
'query': { | ||
'bool': { | ||
'must': [ | ||
{ | ||
'terms': { | ||
DBConstants.authorized_group_name_key: list(belonged_groups), | ||
} | ||
}, | ||
{ | ||
'term': { | ||
DBConstants.action_key: action, | ||
} | ||
} | ||
] | ||
} | ||
} | ||
}) | ||
return [k['_source'] for k in authorized_groups['hits']['hits']] | ||
|
||
def authorize(self, username, resource, action) -> bool: | ||
belonged_groups = set(self.__cognito.get_groups(username)) | ||
authorized_groups = self.__es.query({ | ||
'query': { | ||
'match_all': {} # TODO | ||
} | ||
}) | ||
LOGGER.debug(f'belonged_groups for {username}: {belonged_groups}') | ||
authorized_groups = set([k['_source']['group_name'] for k in authorized_groups['hits']['hits']]) | ||
LOGGER.debug(f'authorized_groups for {resource}-{action}: {authorized_groups}') | ||
if any([k in authorized_groups for k in belonged_groups]): | ||
LOGGER.debug(f'{username} is authorized for {resource}-{action}') | ||
return True | ||
LOGGER.debug(f'{username} is NOT authorized for {resource}-{action}') | ||
return False |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
from cumulus_lambda_functions.lib.aws.aws_cred import AwsCred | ||
|
||
|
||
class AwsCognito(AwsCred): | ||
def __init__(self, user_pool_id: str): | ||
super().__init__() | ||
self.__cognito = self.get_client('cognito-idp') | ||
self.__user_pool_id = user_pool_id | ||
|
||
def get_groups(self, username: str): | ||
response = self.__cognito.admin_list_groups_for_user( | ||
Username=username, | ||
UserPoolId=self.__user_pool_id, | ||
Limit=60, | ||
# NextToken='string' | ||
) | ||
if response is None or 'Groups' not in response: | ||
return [] | ||
belonged_groups = [k['GroupName'] for k in response['Groups']] | ||
return belonged_groups |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
from abc import ABC, abstractmethod | ||
from typing import Any, Union, Callable | ||
|
||
DEFAULT_TYPE = '_doc' | ||
|
||
|
||
class ESAbstract(ABC): | ||
@abstractmethod | ||
def create_index(self, index_name, index_body): | ||
return | ||
|
||
@abstractmethod | ||
def has_index(self, index_name): | ||
return | ||
|
||
@abstractmethod | ||
def create_alias(self, index_name, alias_name): | ||
return | ||
|
||
@abstractmethod | ||
def delete_index(self, index_name): | ||
return | ||
|
||
@abstractmethod | ||
def index_many(self, docs=None, doc_ids=None, doc_dict=None, index=None): | ||
return | ||
|
||
@abstractmethod | ||
def index_one(self, doc, doc_id, index=None): | ||
return | ||
|
||
@abstractmethod | ||
def update_many(self, docs=None, doc_ids=None, doc_dict=None, index=None): | ||
return | ||
|
||
@abstractmethod | ||
def update_one(self, doc, doc_id, index=None): | ||
return | ||
|
||
@staticmethod | ||
@abstractmethod | ||
def get_result_size(result): | ||
return | ||
|
||
@abstractmethod | ||
def query_with_scroll(self, dsl, querying_index=None): | ||
return | ||
|
||
@abstractmethod | ||
def query(self, dsl, querying_index=None): | ||
return | ||
|
||
@abstractmethod | ||
def delete_by_query(self, dsl, querying_index=None): | ||
return | ||
|
||
@abstractmethod | ||
def query_pages(self, dsl, querying_index=None): | ||
return | ||
|
||
@abstractmethod | ||
def query_by_id(self, doc_id): | ||
return |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
from cumulus_lambda_functions.lib.aws.factory_abstract import FactoryAbstract | ||
|
||
|
||
class ESFactory(FactoryAbstract): | ||
NO_AUTH = 'NO_AUTH' | ||
AWS = 'AWS' | ||
|
||
def get_instance(self, class_type, **kwargs): | ||
ct = class_type.upper() | ||
if ct == self.NO_AUTH: | ||
from cumulus_lambda_functions.lib.aws.es_middleware import ESMiddleware | ||
return ESMiddleware(kwargs['index'], kwargs['base_url'], port=kwargs['port']) | ||
if ct == self.AWS: | ||
from cumulus_lambda_functions.lib.aws.es_middleware_aws import EsMiddlewareAws | ||
return EsMiddlewareAws(kwargs['index'], kwargs['base_url'], port=kwargs['port']) | ||
raise ModuleNotFoundError(f'cannot find ES class for {ct}') |
Oops, something went wrong.