def __init__(self, request): self.request = request self._settings = request.registry.settings self._data = self._settings['data'] self.accounting = Accounting() self.authentication = AuthenticationManager() self.token = Token()
class AccountingRestView: """ Implements the main REST API. """ def __init__(self, request): self.request = request self._settings = request.registry.settings self._data = self._settings['data'] self.accounting = Accounting() self.authentication = AuthenticationManager() self.token = Token() @view_config(route_name=Route.READ_ACCOUNTING, request_method='POST', renderer='json') def get(self): """ This method is called from **/engine/api/get_accounting_data**. This method is called in order to get accounting information from user. Arguments: username (str): the username; Returns: success (bool): True if sucessfully get accounting information and False otherwise; error (str): an error message if an error occured and an empty string otherwise. """ msg = '' try: username = self.request.params['username'] token = self.request.params['token'] usr = self.token.verify_token(2, token) if usr != 'invalid token' and usr == username: data = self.accounting.get(username) if data is not None: return { 'success': 'User accounting information read successfully.', 'data': json.dumps(data) } else: return {'error': 'Accounting information not found.'} except KeyError as e: msg = 'Missing mandatory parameter: ' + str(e) raise e except Exception as e: msg = 'Unknown error occurred: ' + str(e) raise e LOG.info(msg) return {'error': msg}
class Authorisation: """ Authorisation class is responsible for managing resource usage rules. """ def __init__(self): self.basedb = BaseDB() self.accounting = Accounting() def verify(self, username, resource_name, resource_category): """ Returns True if username is allowed to access resource. """ resources = list( self.basedb.get(AUTHORISATION_COLLECTION, AUTHORISATION_KEY, username)) for item in resources: for elem in item['resource_rule']: LOG.info('elem: %s' % elem) if elem['resource_name'] == resource_name and\ elem['resource_category'] == resource_category: return True return False def update_resource_item(self, username, resource_name, resource_category): """ Add 1 to used field. """ resources = self.basedb.get(AUTHORISATION_COLLECTION, AUTHORISATION_KEY, username) for item in resources: for elem in item['resource_rule']: LOG.info('elem: %s' % elem) if elem['resource_name'] == resource_name and\ elem['resource_category'] == resource_category: old_item = copy.deepcopy(item) elem['used'] = elem['used'] + 1 res = self.basedb.update(AUTHORISATION_COLLECTION, AUTHORISATION_KEY, username, AUTHORISATION_ITEM, old_item, item) return res def use_resource(self, username, resource_name, resource_category): """ This method is called in order to user a determined resource. Thus, it is responsible for triggering the accounting mechanism and updating the database to increment the number of times that resource was used. """ if self.verify(username, resource_name, resource_category): # add 1 to used field self.update_resource_item(username, resource_name, resource_category) # account it msg = "Resource " + resource_name + " used by: " + username + "." LOG.info('msg: %s' % msg) category = INFO self.accounting.register(username, msg, category) return {'msg': msg} return None def validate_rule(self, rule): """ Validates authorisation object. """ SCHEMA = { 'type': 'object', 'properties': { 'resource_name': { 'type': 'string', 'minLength': 1, 'maxLength': 50 }, 'resource_category': { 'type': 'string', 'minLength': 1, 'maxLength': 50 }, 'max_used': { 'type': 'number' }, 'used': { 'type': 'number' }, }, 'required': ['resource_category', 'resource_name', 'max_used'] } try: validate(rule, SCHEMA) except ValidationError as err: LOG.error('Invalid rule') raise Exception('Invalid rule') from err return True def create(self, username, resource_category, resource_name, max_used): """ Create an authorisation rule on database. Args: username (str): username; resource_name (str): name that identifies the resource being used; rule (dict): rule object. Returns: database response """ rule = { 'resource_category': resource_category, 'resource_name': resource_name, 'max_used': int(max_used), 'used': 0 } if self.validate_rule(rule): result = self.basedb.insert(AUTHORISATION_COLLECTION, AUTHORISATION_KEY, username, AUTHORISATION_ITEM, rule) if result is not None: LOG.info('Rule: ' + json.dumps(rule) + 'successfully created for user: '******'.') return result return None def read(self, username, resource_name, resource_category): """ Read rule information from user. """ resources = self.basedb.get(AUTHORISATION_COLLECTION, AUTHORISATION_KEY, username) for item in resources: for elem in item[AUTHORISATION_ITEM]: if elem['resource_name'] == resource_name and\ elem['resource_category'] == resource_category: return elem return None def update(self, username, resource_name, resource_category, max_allowed): """ Update rule information. """ resources = self.basedb.get(AUTHORISATION_COLLECTION, AUTHORISATION_KEY, username) for item in resources: for elem in item[AUTHORISATION_ITEM]: if elem['resource_name'] == resource_name and\ elem['resource_category'] == resource_category: new_elem = copy.deepcopy(elem) new_elem['max_allowed'] = max_allowed result = self.basedb.update(AUTHORISATION_COLLECTION, AUTHORISATION_KEY, username, AUTHORISATION_ITEM, elem, new_elem) return result return None def delete(self, username, resource_name, resource_category): """ Delete rule information. """ resources = self.basedb.get(AUTHORISATION_COLLECTION, AUTHORISATION_KEY, username) for item in resources: for elem in item[AUTHORISATION_ITEM]: if elem['resource_name'] == resource_name and\ elem['resource_category'] == resource_category: result = self.basedb.remove_list_item( AUTHORISATION_COLLECTION, AUTHORISATION_KEY, username, AUTHORISATION_ITEM, elem) return result return None
def __init__(self): self.basedb = BaseDB() self.accounting = Accounting()
def step_impl(context): with patch.object(BaseDB, 'insert', return_value=True) as mck_insert: accounting = Accounting() accounting.register(context.username, context.msg, context.category) assert mck_insert.called