Skip to content

Commit

Permalink
Merge pull request hyperledger#1060 from anikitinDSR/public/indy-1728
Browse files Browse the repository at this point in the history
[WIP][INDY-1728] add prototype for rules and tests
  • Loading branch information
ashcherbakov authored Dec 13, 2018
2 parents 4be661a + ac4b989 commit a27acd2
Show file tree
Hide file tree
Showing 22 changed files with 1,230 additions and 0 deletions.
Empty file.
74 changes: 74 additions & 0 deletions indy_common/authorize/auth_actions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
from typing import NamedTuple


from abc import ABCMeta, abstractmethod


RULE_DELIMETER = "--"
ADD_PREFIX = "ADD"
EDIT_PREFIX = "EDIT"

ActionDef = NamedTuple('ActionDef', [('prefix', str), ('txn_type', str), ('field', str), ('old_value', str), ('new_value', str)])


def compile_action_id(txn_type,
field,
old_value,
new_value,
prefix='') -> str:
return RULE_DELIMETER.join([prefix,
txn_type,
field,
old_value,
new_value])


def split_action_id(action_id) -> ActionDef:
return ActionDef(*action_id.split(RULE_DELIMETER))


"""
Action's classes
"""


class AbstractAuthAction(metaclass=ABCMeta):
def __init__(self, txn_type):
pass

@abstractmethod
def get_action_id(self):
raise NotImplementedError()


class AuthActionAdd(AbstractAuthAction):
def __init__(self, txn_type, field=None, value=None, is_owner=True):
self.txn_type = txn_type
self.field = field
self.value = value
self.is_owner = is_owner

def get_action_id(self):
return compile_action_id(txn_type=self.txn_type,
field=self.field,
old_value='*',
new_value=self.value,
prefix=ADD_PREFIX)


class AuthActionEdit(AbstractAuthAction):
def __init__(self, txn_type, field=None, old_value=None, new_value=None, is_owner=True):
self.txn_type = txn_type
self.field = field
self.old_value = old_value
self.new_value = new_value
self.is_owner = is_owner

def get_action_id(self):
return compile_action_id(txn_type=self.txn_type,
field=self.field,
old_value=self.old_value,
new_value=self.new_value,
prefix=EDIT_PREFIX)
58 changes: 58 additions & 0 deletions indy_common/authorize/auth_cons_strategies.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
from abc import abstractmethod, ABCMeta

from indy_common.authorize.auth_actions import split_action_id
from indy_common.authorize.auth_constraints import AbstractAuthConstraint


class AbstractAuthStrategy(metaclass=ABCMeta):
def __init__(self, auth_map):
self.auth_map = auth_map

@abstractmethod
def get_auth_constraint(self, action_id) -> AbstractAuthConstraint:
raise NotImplementedError()

@abstractmethod
def _find_auth_constraint_key(self, action_id):
raise NotImplementedError()

@staticmethod
def is_accepted_action_id(from_auth_map, from_req):
am = split_action_id(from_auth_map)
r = split_action_id(from_req)
if r.prefix != am.prefix:
return False
if r.txn_type != am.txn_type:
return False
if r.field != am.field and \
am.field != '*':
return False
if r.old_value != am.old_value and \
am.old_value != '*':
return False
if r.new_value != am.new_value and \
am.new_value != '*':
return False
return True


class LocalAuthStrategy(AbstractAuthStrategy):

def get_auth_constraint(self, action_id) -> AbstractAuthConstraint:
am_id = self._find_auth_constraint_key(action_id)
return self.auth_map.get(am_id)

def _find_auth_constraint_key(self, action_id):
for am_id in self.auth_map.keys():
if self.is_accepted_action_id(am_id, action_id):
return am_id


class ConfigLedgerAuthStrategy(AbstractAuthStrategy):

def get_auth_constraint(self, action_id) -> AbstractAuthConstraint:
"""Get constraints from config ledger"""
pass

def _find_auth_constraint_key(self, acton_id):
pass
52 changes: 52 additions & 0 deletions indy_common/authorize/auth_constraints.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
from abc import ABCMeta, abstractmethod
from typing import List


ROLE_CONSTRAINT_ID = 'ROLE'
AND_CONSTRAINT_ID = 'AND'
OR_CONSTRAINT_ID = 'OR'


class AbstractAuthConstraint(metaclass=ABCMeta):
def __init__(self):
self.constraint_id = ''


class AuthConstraint(AbstractAuthConstraint):
def __init__(self, role, sig_count, need_to_be_owner=False, metadata={}):
self.role = role
self.sig_count = sig_count
self.need_to_be_owner = need_to_be_owner
self.metadata = metadata
self.constraint_id = ROLE_CONSTRAINT_ID


class AuthConstraintAnd(AbstractAuthConstraint):
def __init__(self, auth_constraints):
self.auth_constraints = auth_constraints
self.constraint_id = AND_CONSTRAINT_ID


class AuthConstraintOr(AbstractAuthConstraint):
def __init__(self, auth_constraints):
self.auth_constraints = auth_constraints
self.constraint_id = OR_CONSTRAINT_ID


class AbstractAuthConstraintParser(metaclass=ABCMeta):
@staticmethod
@abstractmethod
def is_accepted(constraint_results: List):
raise NotImplementedError()


class AuthConstraintParserOr(AbstractAuthConstraintParser):
@staticmethod
def is_accepted(constraint_results: List):
return any(constraint_results)


class AuthConstraintParserAnd(AbstractAuthConstraintParser):
@staticmethod
def is_accepted(constraint_results: List):
return all(constraint_results)
163 changes: 163 additions & 0 deletions indy_common/authorize/auth_map.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
from indy_common.authorize.auth_actions import AuthActionAdd, AuthActionEdit
from indy_common.authorize.auth_constraints import AuthConstraint, AuthConstraintOr
from indy_common.constants import TRUST_ANCHOR, POOL_CONFIG, VALIDATOR_INFO, POOL_UPGRADE, POOL_RESTART, NODE, \
CLAIM_DEF, SCHEMA, NYM, ROLE
from plenum.common.constants import TRUSTEE, STEWARD, VERKEY


addNewTrustee = AuthActionAdd(txn_type=NYM,
field=ROLE,
value=TRUSTEE)

addNewSteward = AuthActionAdd(txn_type=NYM,
field=ROLE,
value=STEWARD)

addNewTrustAnchor = AuthActionAdd(txn_type=NYM,
field=ROLE,
value=TRUST_ANCHOR)


addNewIdentityOwner = AuthActionAdd(txn_type=NYM,
field='role',
value='')


blacklistingTrustee = AuthActionEdit(txn_type=NYM,
field=ROLE,
old_value=TRUSTEE,
new_value='')

blacklistingSteward = AuthActionEdit(txn_type=NYM,
field=ROLE,
old_value=STEWARD,
new_value='')

blacklistingTrustAnchor = AuthActionEdit(txn_type=NYM,
field=ROLE,
old_value=TRUST_ANCHOR,
new_value='')

keyRotation = AuthActionEdit(txn_type=NYM,
field=VERKEY,
old_value='*',
new_value='*')


addSchema = AuthActionAdd(txn_type=SCHEMA,
field='*',
value='*')

editSchema = AuthActionEdit(txn_type=SCHEMA,
field='*',
old_value='*',
new_value='*')

addClaimDef = AuthActionAdd(txn_type=CLAIM_DEF,
field='*',
value='*')

editClaimDef = AuthActionEdit(txn_type=CLAIM_DEF,
field='*',
old_value='*',
new_value='*')


addingNewNode = AuthActionAdd(txn_type=NODE,
field='services',
value='[VALIDATOR]')

demoteNode = AuthActionEdit(txn_type=NODE,
field='services',
old_value='[VALIDATOR]',
new_value='[]')

promoteNode = AuthActionEdit(txn_type=NODE,
field='services',
old_value='[]',
new_value='[VALIDATOR]')


changeNodeIp = AuthActionEdit(txn_type=NODE,
field='node_ip',
old_value='*',
new_value='*')

changeNodePort = AuthActionEdit(txn_type=NODE,
field='node_port',
old_value='*',
new_value='*')

changeClientIp = AuthActionEdit(txn_type=NODE,
field='client_ip',
old_value='*',
new_value='*')

changeClientPort = AuthActionEdit(txn_type=NODE,
field='client_port',
old_value='*',
new_value='*')

changeBlsKey = AuthActionEdit(txn_type=NODE,
field='blskey',
old_value='*',
new_value='*')

startUpgrade = AuthActionAdd(txn_type=POOL_UPGRADE,
field='action',
value='start')

cancelUpgrade = AuthActionEdit(txn_type=POOL_UPGRADE,
field='action',
old_value='start',
new_value='cancel')

poolRestart = AuthActionAdd(txn_type=POOL_RESTART,
field='action',
value='*')

poolConfig = AuthActionAdd(txn_type=POOL_CONFIG,
field='action',
value='*')

validatorInfo = AuthActionAdd(txn_type=VALIDATOR_INFO,
field='*',
value='*')

authMap = {addNewTrustee.get_action_id(): AuthConstraint(TRUSTEE, 1),
addNewSteward.get_action_id(): AuthConstraint(TRUSTEE, 1),
addNewTrustAnchor.get_action_id(): AuthConstraintOr([AuthConstraint(TRUSTEE, 1),
AuthConstraint(STEWARD, 1)]),
addNewIdentityOwner.get_action_id(): AuthConstraintOr([AuthConstraint(TRUSTEE, 1),
AuthConstraint(STEWARD, 1),
AuthConstraint(TRUST_ANCHOR, 1)]),
blacklistingTrustee.get_action_id(): AuthConstraint(TRUSTEE, 1),
blacklistingSteward.get_action_id(): AuthConstraint(TRUSTEE, 1),
blacklistingTrustAnchor.get_action_id(): AuthConstraint(TRUSTEE, 1),
keyRotation.get_action_id(): AuthConstraint(role='*',
sig_count=1,
need_to_be_owner=True),
addSchema.get_action_id(): AuthConstraintOr([AuthConstraint(TRUSTEE, 1),
AuthConstraint(STEWARD, 1),
AuthConstraint(TRUST_ANCHOR, 1)]),
editSchema.get_action_id(): AuthConstraint(None, 1),
addClaimDef.get_action_id(): AuthConstraintOr([AuthConstraint(TRUSTEE, 1),
AuthConstraint(STEWARD, 1),
AuthConstraint(TRUST_ANCHOR, 1)]),
editClaimDef.get_action_id(): AuthConstraint('*', 1, need_to_be_owner=True),
addingNewNode.get_action_id(): AuthConstraint(STEWARD, 1, need_to_be_owner=True),
demoteNode.get_action_id(): AuthConstraintOr([AuthConstraint(TRUSTEE, 1),
AuthConstraint(STEWARD, 1, need_to_be_owner=True)]),
promoteNode.get_action_id(): AuthConstraintOr([AuthConstraint(TRUSTEE, 1),
AuthConstraint(STEWARD, 1, need_to_be_owner=True)]),
changeNodeIp.get_action_id(): AuthConstraint(STEWARD, 1, need_to_be_owner=True),
changeNodePort.get_action_id(): AuthConstraint(STEWARD, 1, need_to_be_owner=True),
changeClientIp.get_action_id(): AuthConstraint(STEWARD, 1, need_to_be_owner=True),
changeClientPort.get_action_id(): AuthConstraint(STEWARD, 1, need_to_be_owner=True),
changeBlsKey.get_action_id(): AuthConstraint(STEWARD, 1, need_to_be_owner=True),
startUpgrade.get_action_id(): AuthConstraint(TRUSTEE, 1),
cancelUpgrade.get_action_id(): AuthConstraint(TRUSTEE, 1),
poolRestart.get_action_id(): AuthConstraint(TRUSTEE, 1),
poolConfig.get_action_id(): AuthConstraint(TRUSTEE, 1),
validatorInfo.get_action_id(): AuthConstraintOr([AuthConstraint(TRUSTEE, 1),
AuthConstraint(STEWARD, 1)])}
Loading

0 comments on commit a27acd2

Please sign in to comment.