예제 #1
0
    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)
예제 #2
0
 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)))
예제 #3
0
    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))
예제 #4
0
    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)
예제 #5
0
    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')
예제 #7
0
    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")
예제 #8
0
 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)))
예제 #9
0
 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)))
예제 #10
0
 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')
예제 #12
0
 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")
예제 #13
0
 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)
예제 #14
0
 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']] = {}
예제 #15
0
    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")
예제 #16
0
 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)
예제 #17
0
 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)
예제 #18
0
 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)
예제 #19
0
 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)
예제 #20
0
 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)
예제 #21
0
 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)))
예제 #22
0
 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)
예제 #23
0
    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))
예제 #24
0
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)
예제 #25
0
 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))
예제 #28
0
    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))
예제 #30
0
 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)))