def checkRequestAuthorized(self, request: Request): op = request.operation typ = op[TXN_TYPE] s = self.graphStore # type: IdentityGraph origin = request.identifier originRole = s.getRole(origin) if typ == NYM: role = op.get(ROLE) or USER authorizedAdder = self.authorizedAdders[role] if originRole not in authorizedAdder: raise UnauthorizedClientRequest( request.identifier, request.reqId, "{} cannot add {}".format(originRole, role)) elif typ == ATTRIB: if op.get(TARGET_NYM) and \ op[TARGET_NYM] != request.identifier and \ not s.getSponsorFor(op[TARGET_NYM]) == origin: raise UnauthorizedClientRequest( request.identifier, request.reqId, "Only user's sponsor can add attribute for that user") # TODO: Just for now. Later do something meaningful here elif typ in [ DISCLO, GET_ATTR, CRED_DEF, GET_CRED_DEF, ISSUER_KEY, GET_ISSUER_KEY ]: pass else: return super().checkRequestAuthorized(request)
def validate(self, req: Request): status = None operation = req.operation typ = operation.get(TXN_TYPE) if typ not in [POOL_RESTART]: return origin = req.identifier try: origin_role = self.idrCache.getRole(origin, isCommitted=False) except BaseException: raise UnauthorizedClientRequest( req.identifier, req.reqId, "Nym {} not added to the ledger yet".format(origin)) action = "" if typ == POOL_RESTART: action = operation.get(ACTION) r, msg = Authoriser.authorised(typ, origin_role, field=ACTION, oldVal=status, newVal=action) if not r: raise UnauthorizedClientRequest( req.identifier, req.reqId, "{} cannot do restart".format( Roles.nameFromValue(origin_role)))
def validate(self, req: Request): status = None operation = req.operation typ = operation.get(TXN_TYPE) if typ not in [POOL_UPGRADE, POOL_CONFIG]: return origin = req.identifier try: originRole = self.idrCache.getRole(origin, isCommitted=False) except BaseException: raise UnauthorizedClientRequest( req.identifier, req.reqId, "Nym {} not added to the ledger yet".format(origin)) if typ == POOL_UPGRADE: currentVersion = Upgrader.getVersion() targetVersion = req.operation[VERSION] if Upgrader.compareVersions(currentVersion, targetVersion) < 0: # currentVersion > targetVersion raise InvalidClientRequest( req.identifier, req.reqId, "Upgrade to lower version is not allowed") trname = IndyTransactions.POOL_UPGRADE.name action = operation.get(ACTION) # TODO: Some validation needed for making sure name and version # present txn = self.upgrader.get_upgrade_txn( lambda txn: txn.get( NAME, None) == req.operation.get( NAME, None) and txn.get(VERSION) == req.operation.get(VERSION), reverse=True) if txn: status = txn.get(ACTION, None) if status == START and action == START: raise InvalidClientRequest( req.identifier, req.reqId, "Upgrade '{}' is already scheduled".format( req.operation.get(NAME))) elif typ == POOL_CONFIG: trname = IndyTransactions.POOL_CONFIG.name action = None status = None r, msg = Authoriser.authorised( typ, originRole, field=ACTION, oldVal=status, newVal=action) if not r: raise UnauthorizedClientRequest( req.identifier, req.reqId, "{} cannot do {}".format( Roles.nameFromValue(originRole), trname))
def _validateExistingNym(self, req: Request, op, originRole, nymData): unauthorized = False reason = None origin = req.identifier owner = self.idrCache.getOwnerFor(op[TARGET_NYM], isCommitted=False) isOwner = origin == owner if not originRole == TRUSTEE and not isOwner: reason = '{} is neither Trustee nor owner of {}' \ .format(origin, op[TARGET_NYM]) unauthorized = True if not unauthorized: updateKeys = [ROLE, VERKEY] for key in updateKeys: if key in op: newVal = op[key] oldVal = nymData.get(key) if oldVal != newVal: r, msg = Authoriser.authorised( NYM, key, originRole, oldVal=oldVal, newVal=newVal, isActorOwnerOfSubject=isOwner) if not r: unauthorized = True reason = "{} cannot update {}".\ format(Roles.nameFromValue(originRole), key) break if unauthorized: raise UnauthorizedClientRequest(req.identifier, req.reqId, reason)
def _validate_fees_can_pay(self, request, inputs, outputs, required_fees): """ Calculate and verify that inputs and outputs for fees can both be paid and change is properly specified This function ASSUMES that validation of the fees for the request has already been done. :param request: :param required_fees: :return: """ try: sum_inputs = self.utxo_cache.sum_inputs(inputs, is_committed=False) except UTXOError as ex: raise InvalidFundsError(request.identifier, request.reqId, "{}".format(ex)) except Exception as ex: error = 'Exception {} while processing inputs/outputs'.format(ex) raise UnauthorizedClientRequest(request.identifier, request.reqId, error) else: change_amount = sum([a[AMOUNT] for a in outputs]) expected_amount = change_amount + required_fees TokenStaticHelper.validate_given_inputs_outputs( sum_inputs, change_amount, expected_amount, request, 'fees: {}'.format(required_fees))
def dynamic_validation(self, request: Request): self._validate_request_type(request) operation = request.operation data = operation.get(DATA) if data['id'] not in self.auctions: raise UnauthorizedClientRequest(request.identifier, request.reqId, 'unknown auction')
def authorize(self, req: Request): typ = req.operation.get(TXN_TYPE) if typ in [TXN_AUTHOR_AGREEMENT, TXN_AUTHOR_AGREEMENT_AML] \ and not self._is_trustee(req.identifier): raise UnauthorizedClientRequest(req.identifier, req.reqId, "Only trustee can update transaction author agreement and AML")
def _validate_schema(self, req: Request): # we can not add a Schema with already existent NAME and VERSION # sine a Schema needs to be identified by seqNo identifier = req.identifier operation = req.operation schema_name = operation[DATA][NAME] schema_version = operation[DATA][VERSION] schema, _, _, _ = self.getSchema(author=identifier, schemaName=schema_name, schemaVersion=schema_version) if schema: raise InvalidClientRequest( identifier, req.reqId, '{} can have one and only one SCHEMA with ' 'name {} and version {}'.format(identifier, schema_name, schema_version)) try: origin_role = self.idrCache.getRole(req.identifier, isCommitted=False) or None except BaseException: raise UnknownIdentifier(req.identifier, req.reqId) r, msg = Authoriser.authorised(typ=SCHEMA, actorRole=origin_role) if not r: raise UnauthorizedClientRequest( req.identifier, req.reqId, "{} cannot add schema".format( Roles.nameFromValue(origin_role)))
def _validate_claim_def(self, req: Request): # we can not add a Claim Def with existent ISSUER_DID # sine a Claim Def needs to be identified by seqNo ref = req.operation[REF] try: txn = self.ledger.getBySeqNo(ref) except KeyError: raise InvalidClientRequest( req.identifier, req.reqId, "Mentioned seqNo ({}) doesn't exist.".format(ref)) if txn['txn']['type'] != SCHEMA: raise InvalidClientRequest( req.identifier, req.reqId, "Mentioned seqNo ({}) isn't seqNo of the schema.".format(ref)) try: origin_role = self.idrCache.getRole(req.identifier, isCommitted=False) or None except BaseException: raise UnknownIdentifier(req.identifier, req.reqId) # only owner can update claim_def, # because his identifier is the primary key of claim_def r, msg = Authoriser.authorised(typ=CLAIM_DEF, actorRole=origin_role, isActorOwnerOfSubject=True) if not r: raise UnauthorizedClientRequest( req.identifier, req.reqId, "{} cannot add claim def".format( Roles.nameFromValue(origin_role)))
def authorize(self, request): domain_state = self.database_manager.get_database( DOMAIN_LEDGER_ID).state if not is_trustee(domain_state, request.identifier, is_committed=False): raise UnauthorizedClientRequest(request.identifier, request.reqId, "Only trustee can freeze ledgers")
def rejectingMethod(self, req): names[self.name] += 1 # Raise rejection for last request of batch if tconf.Max3PCBatchSize - names[self.name] == 0: raise UnauthorizedClientRequest(req.identifier, req.reqId, 'Simulated rejection')
def _validateAttrib(self, req: Request): origin = req.identifier op = req.operation if op.get(TARGET_NYM) and op[TARGET_NYM] != req.identifier and \ not self.idrCache.getOwnerFor(op[TARGET_NYM], isCommitted=False) == origin: raise UnauthorizedClientRequest( req.identifier, req.reqId, "Only identity owner/guardian can add attribute " "for that identity")
def additional_dynamic_validation(self, request: Request, req_pp_time: Optional[int]): node_nym = request.operation.get(TARGET_NYM) if self.get_from_state(node_nym, is_committed=False): error = self._auth_error_while_updating_node(request) else: error = self._auth_error_while_adding_node(request) if error: raise UnauthorizedClientRequest(request.identifier, request.reqId, error)
def validate(self, req: Request): operation = req.operation data = operation.get(DATA) if operation.get(TXN_TYPE) != AUCTION_START: if data['id'] not in self.auctions: raise UnauthorizedClientRequest(req.identifier, req.reqId, 'unknown auction') else: self.auctions[data['id']] = {}
def authorize(database_manager, req: Request): typ = req.operation.get(TXN_TYPE) domain_state = database_manager.get_database(DOMAIN_LEDGER_ID).state if typ in [TXN_AUTHOR_AGREEMENT, TXN_AUTHOR_AGREEMENT_AML] \ and not is_trustee(domain_state, req.identifier, is_committed=False): raise UnauthorizedClientRequest( req.identifier, req.reqId, "Only trustee can update transaction author agreement and AML")
def checkRequestAuthorized(self, request): typ = request.operation.get(TXN_TYPE) error = None if typ == NEW_NODE: error = self.authErrorWhileAddingNode(request) if typ in (CHANGE_HA, CHANGE_KEYS): error = self.authErrorWhileUpdatingNode(request) if error: raise UnauthorizedClientRequest(request.identifier, request.reqId, error)
def dynamic_validation(self, request: Request): self._validate_request_type(request) node_nym = request.operation.get(TARGET_NYM) if self._get_node_data(node_nym, is_committed=False): error = self._auth_error_while_updating_node(request) else: error = self._auth_error_while_adding_node(request) if error: raise UnauthorizedClientRequest(request.identifier, request.reqId, error)
def validate(self, req: Request, config=None): typ = req.operation.get(TXN_TYPE) error = None if typ == NODE: nodeNym = req.operation.get(TARGET_NYM) if self.getNodeData(nodeNym, isCommitted=False): error = self.authErrorWhileUpdatingNode(req) else: error = self.authErrorWhileAddingNode(req) if error: raise UnauthorizedClientRequest(req.identifier, req.reqId, error)
def validate(self, request: Request, action_list: [AbstractAuthAction]): for action in action_list: action_id = action.get_action_id() auth_constraint = self.auth_cons_strategy.get_auth_constraint(action_id) if auth_constraint: try: super().authorize(request=request, auth_constraint=auth_constraint, auth_action=action) except AuthValidationError as exp: logger.warning("Request {} cannot be authorized by reason: {}".format(request, exp.reason)) raise UnauthorizedClientRequest(request.identifier, request.reqId, exp.reason) return True error_msg = "There is no authorization constraints for request: {}".format(request) logger.warning(error_msg) raise UnauthorizedClientRequest(request.identifier, request.reqId, error_msg)
def patched_dynamic_validation(self, request, req_pp_time): self._validate_request_type(request) identifier, req_id, operation = get_request_data(request) error = None if operation.get(ROLE) == STEWARD: if self._steward_threshold_exceeded(self.config): error = "New stewards cannot be added by other stewards " \ "as there are already {} stewards in the system". \ format(self.config.stewardThreshold) if error: raise UnauthorizedClientRequest(identifier, req_id, error)
def _validateNewNym(self, req: Request, op, originRole): role = op.get(ROLE) r, msg = Authoriser.authorised(NYM, ROLE, originRole, oldVal=None, newVal=role) if not r: raise UnauthorizedClientRequest( req.identifier, req.reqId, "{} cannot add {}".format(Roles.nameFromValue(originRole), Roles.nameFromValue(role)))
def checkRequestAuthorized(self, request): typ = request.operation.get(TXN_TYPE) error = None if typ == NODE: nodeNym = request.operation.get(TARGET_NYM) if self.nodeExistsInLedger(nodeNym): error = self.authErrorWhileUpdatingNode(request) else: error = self.authErrorWhileAddingNode(request) if error: raise UnauthorizedClientRequest(request.identifier, request.reqId, error)
def validate(self, req: Request, config=None): operation = req.operation typ = operation.get(TXN_TYPE) if typ not in [POOL_UPGRADE, POOL_CONFIG]: return origin = req.identifier try: originRole = self.idrCache.getRole(origin, isCommitted=False) except: raise UnauthorizedClientRequest( req.identifier, req.reqId, "Nym {} not added to the ledger yet".format(origin)) if typ == POOL_UPGRADE: trname = SovrinTransactions.POOL_UPGRADE.name action = operation.get(ACTION) # TODO: Some validation needed for making sure name and version # present status = self.upgrader.statusInLedger(req.operation.get(NAME), req.operation.get(VERSION)) if status == START and action == START: raise InvalidClientRequest( req.identifier, req.reqId, "Upgrade '{}' is already scheduled".format( req.operation.get(NAME))) elif typ == POOL_CONFIG: trname = SovrinTransactions.POOL_CONFIG.name action = None status = None r, msg = Authoriser.authorised(typ, ACTION, originRole, oldVal=status, newVal=action) if not r: raise UnauthorizedClientRequest( req.identifier, req.reqId, "{} cannot do {}".format(Roles.nameFromValue(originRole), trname))
def validate_multi_sig_txn(request, required_role, domain_state, threshold: int): # Takes a request, a provided role and expects to find at least a threshold number # senders roles with provided role. Can raise an exception senders = request.all_identifiers if len(senders) >= threshold: authorized_sender_count = 0 for idr in senders: if DomainRequestHandler.get_role(domain_state, idr, required_role): authorized_sender_count += 1 if authorized_sender_count == threshold: return error = 'only Trustees can send this transaction' raise UnauthorizedClientRequest(senders, getattr(request, f.REQ_ID.nm, None), error) else: error = 'Request needs at least {} signers but only {} found'. \ format(threshold, len(senders)) raise UnauthorizedClientRequest(senders, getattr(request, f.REQ_ID.nm, None), error)
def dynamic_validation(self, request: Request, req_pp_time: Optional[int]): self._validate_request_type(request) identifier, req_id, operation = get_request_data(request) error = None if not is_steward(self.state, identifier, is_committed=False): error = "Only Steward is allowed to do these transactions" if operation.get(ROLE) == STEWARD: if self._steward_threshold_exceeded(self.config): error = "New stewards cannot be added by other stewards " \ "as there are already {} stewards in the system". \ format(self.config.stewardThreshold) if error: raise UnauthorizedClientRequest(identifier, req_id, error)
def validate(self, req: Request, config=None): if req.operation.get(TXN_TYPE) == NYM: origin = req.identifier error = None if not self.isSteward(self.state, origin, isCommitted=False): error = "Only Steward is allowed to do these transactions" if req.operation.get(ROLE) == STEWARD: if self.stewardThresholdExceeded(config): error = "New stewards cannot be added by other stewards " \ "as there are already {} stewards in the system".\ format(config.stewardThreshold) if error: raise UnauthorizedClientRequest(req.identifier, req.reqId, error)
def _get_deducted_fees_non_xfer(self, request, required_fees): if not self.has_fees(request): error = 'fees not present or improperly formed' raise UnauthorizedClientRequest(request.identifier, request.reqId, error) else: try: sum_inputs = self.utxo_cache.sum_inputs(request.fees[0], is_committed=False) except UTXOError as ex: raise InvalidFundsError(request.identifier, request.reqId, "{}".format(ex)) else: change_amount = sum([a[AMOUNT] for a in self.get_change_for_fees(request)]) expected_amount = change_amount + required_fees TokenReqHandler.validate_given_inputs_outputs(sum_inputs, change_amount, expected_amount, request, 'fees: {}'.format(required_fees))
def _validateAttrib(self, req: Request): origin = req.identifier op = req.operation if not (not op.get(TARGET_NYM) or self.hasNym(op[TARGET_NYM], isCommitted=False)): raise InvalidClientRequest( origin, req.reqId, '{} should be added before adding ' 'attribute for it'.format(TARGET_NYM)) if op.get(TARGET_NYM) and op[TARGET_NYM] != req.identifier and \ not self.idrCache.getOwnerFor(op[TARGET_NYM], isCommitted=False) == origin: raise UnauthorizedClientRequest( req.identifier, req.reqId, "Only identity owner/guardian can add attribute " "for that identity")
def _get_deducted_fees_xfer(self, request, required_fees): try: sum_inputs = TokenReqHandler.sum_inputs(self.utxo_cache, request, is_committed=False) sum_outputs = TokenReqHandler.sum_outputs(request) except InvalidClientMessageException as ex: raise ex except Exception as ex: error = 'Exception {} while processing inputs/outputs'.format(ex) raise UnauthorizedClientRequest(request.identifier, request.reqId, error) else: expected_amount = sum_outputs + required_fees TokenReqHandler.validate_given_inputs_outputs(sum_inputs, sum_outputs, expected_amount, request, 'fees: {}'.format(required_fees))
def _validate_claim_def(self, req: Request): # we can not add a Claim Def with existent ISSUER_DID # sine a Claim Def needs to be identified by seqNo try: origin_role = self.idrCache.getRole(req.identifier, isCommitted=False) or None except BaseException: raise UnknownIdentifier(req.identifier, req.reqId) # only owner can update claim_def, # because his identifier is the primary key of claim_def r, msg = Authoriser.authorised(typ=CLAIM_DEF, actorRole=origin_role, isActorOwnerOfSubject=True) if not r: raise UnauthorizedClientRequest( req.identifier, req.reqId, "{} cannot add claim def".format( Roles.nameFromValue(origin_role)))