def authorised(typ, field, actorRole, oldVal=None, newVal=None, isActorOwnerOfSubject=None) -> (bool, str): oldVal = '' if oldVal is None else \ str(oldVal).replace('"', '').replace("'", '') newVal = '' if newVal is None else \ str(newVal).replace('"', '').replace("'", '') key = '_'.join([typ, field, oldVal, newVal]) if key not in Authoriser.AuthMap: anyKey = '_'.join([typ, field, '<any>', '<any>']) if anyKey not in Authoriser.AuthMap: msg = "key '{}' not found in authorized map". \ format(key) logger.debug(msg) return False, msg else: key = anyKey roles = Authoriser.AuthMap[key] if actorRole not in roles: roles_as_str = [Roles.nameFromValue(role) for role in roles.keys()] return False, '{} not in allowed roles {}'.\ format(Roles.nameFromValue(actorRole), roles_as_str) roleDetails = roles[actorRole] if len(roleDetails) == 0: return True, '' else: r = OWNER in roleDetails and isActorOwnerOfSubject msg = '' if r else 'Only owner is allowed' return r, msg
def authorised(typ, actorRole, field=None, oldVal=None, newVal=None, isActorOwnerOfSubject=None) -> (bool, str): if not Authoriser.auth_map: Authoriser.auth_map = generate_auth_map(Authoriser.ValidRoles) field = field if field is not None else "" oldVal = '' if oldVal is None else \ str(oldVal).replace('"', '').replace("'", '') newVal = '' if newVal is None else \ str(newVal).replace('"', '').replace("'", '') key = '_'.join([typ, field, oldVal, newVal]) if key not in Authoriser.auth_map: any_value = '_'.join([typ, field, '<any>', '<any>']) if any_value not in Authoriser.auth_map: any_field = '_'.join([typ, "<any>", '<any>', '<any>']) if any_field not in Authoriser.auth_map: msg = "key '{}' not found in authorized map".format(key) logger.debug(msg) return False, msg else: key = any_field else: key = any_value roles = Authoriser.auth_map[key] if actorRole not in roles: roles_as_str = [Roles.nameFromValue(role) for role in roles.keys()] return False, '{} not in allowed roles {}'. \ format(Roles.nameFromValue(actorRole), roles_as_str) roleDetails = roles[actorRole] if len(roleDetails) == 0: return True, '' else: r = OWNER in roleDetails and isActorOwnerOfSubject msg = '' if r else 'Only owner is allowed' return r, msg
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 _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 _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 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 _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_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_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, with_proof=False ) 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 _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(self, req: Request): status = None operation = req.operation typ = operation.get(TXN_TYPE) if typ not in self.operation_types: 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)) r = False if typ == POOL_RESTART: action = operation.get(ACTION) r, msg = Authoriser.authorised(typ, origin_role, field=ACTION, oldVal=status, newVal=action) elif typ == VALIDATOR_INFO: r, msg = Authoriser.authorised(typ, origin_role) if not r: raise UnauthorizedClientRequest( req.identifier, req.reqId, "{} cannot do action with type = {}".format( Roles.nameFromValue(origin_role), typ))
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, ACTION, originRole, oldVal=status, newVal=action) if not r: raise UnauthorizedClientRequest( req.identifier, req.reqId, "{} cannot do {}".format( Roles.nameFromValue(originRole), trname))
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 _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)))
def _validateExistingNym(self, req: Request, op, originRole, nymData): origin = req.identifier owner = self.idrCache.getOwnerFor(op[TARGET_NYM], isCommitted=False) isOwner = origin == owner 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: raise UnauthorizedClientRequest( req.identifier, req.reqId, "{} cannot update {}".format( Roles.nameFromValue(originRole), key))
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)) )
def testNameFromValue(): assert Roles.nameFromValue("2") == "STEWARD" assert Roles.nameFromValue("0") == "TRUSTEE" assert Roles.nameFromValue("101") == "ENDORSER" assert Roles.nameFromValue(None) == "None role"
def testNameFromValue(): assert Roles.nameFromValue("2") == "STEWARD" assert Roles.nameFromValue("0") == "TRUSTEE" assert Roles.nameFromValue("100") == "TGB" assert Roles.nameFromValue("101") == "TRUST_ANCHOR" assert Roles.nameFromValue(None) == "None 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: pkt_to_upgrade = req.operation.get(PACKAGE, getConfig().UPGRADE_ENTRY) if pkt_to_upgrade: currentVersion, cur_deps = self.curr_pkt_info(pkt_to_upgrade) if not currentVersion: raise InvalidClientRequest( req.identifier, req.reqId, "Packet {} is not installed and cannot be upgraded". format(pkt_to_upgrade)) if all([APP_NAME not in d for d in cur_deps]): raise InvalidClientRequest( req.identifier, req.reqId, "Packet {} doesn't belong to pool".format( pkt_to_upgrade)) else: raise InvalidClientRequest(req.identifier, req.reqId, "Upgrade packet name is empty") targetVersion = req.operation[VERSION] reinstall = req.operation.get(REINSTALL, False) if not Upgrader.is_version_upgradable(currentVersion, targetVersion, reinstall): # currentVersion > targetVersion raise InvalidClientRequest(req.identifier, req.reqId, "Version is not upgradable") 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: get_payload_data(txn).get(NAME, None) == req. operation.get(NAME, None) and get_payload_data(txn).get( VERSION) == req.operation.get(VERSION), reverse=True) if txn: status = get_payload_data(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 get_named_role(role_code): try: return Roles.nameFromValue(role_code) except ValueError: return "Unknown role"