Quantum的权限认证(3)

本文地址:http://blog.csdn.net/spch2008/article/details/9700071

这里主要说一下,权限信息的加载过程。

quantum\openstack\common\policy.py中

全局变量_checks = {}是一个字典,存放各种权限验证类。比如;

{'rule':RuleCheck, 'role':RoleCheck},由于使用了装饰器,所以,此模块被加载时,_checks就被初始化了,具体可参见带参数的装饰器。

def register(name, func=None):

    def decorator(func):
        _checks[name] = func
        return func

    if func:
        return decorator(func)

    return decorator

@register("role")
class RoleCheck(Check):
    def __call__(self, target, creds):
        """Check that there is a matching role in the cred dict."""

        return self.match.lower() in [x.lower() for x in creds['roles']]
由于register只传递一个参数'role',所以,register中func值为None,用返回的decorator函数装饰RoleCheck类,将类存放于_check中。
class Rules(dict):
    
    @classmethod
    def load_json(cls, data, default_rule=None):
        
        rules = dict((k, parse_rule(v)) for k, v in
                     jsonutils.loads(data).items())
          
        return cls(rules, default_rule)
data为policy.json中的数据,jsonutils.loads将数据组织成字典返回。所以,对于数据
{
"admin_or_owner": [["role:admin"], ["tenant_id:%(tenant_id)s"]],  
"get_port": [["rule:admin_or_owner"]],
} 
实际返回的就是上述格式的字典,然后进行列表解析。
def parse_rule(rule):
    
    if isinstance(rule, basestring):
        return _parse_text_rule(rule)
    return _parse_list_rule(rule)
rule是一个[["role:admin"], ["tenant_id:%(tenant_id)s"]]存放列表的列表,所以继续调用_parse_list_rule
def _parse_list_rule(rule):
    #空条目,例如[],返回TrueCheck,永真
    if not rule:
        return TrueCheck()
		
    or_list = []
    for inner_rule in rule:
        if isinstance(inner_rule, basestring):
            inner_rule = [inner_rule]
   
        and_list = [_parse_check(r) for r in inner_rule]

        if len(and_list) == 1:
            or_list.append(and_list[0])
        else:
            or_list.append(AndCheck(and_list))

    # If we have only one check, omit the "or"
    if len(or_list) == 0:
        return FalseCheck()
    elif len(or_list) == 1:
        return or_list[0]

    return OrCheck(or_list)
得到的and_list如果只有一个,则可以直接加入or_list,如果有多个,需要合成一个AndCheck对象,表示每一个都需要匹配。

最终,如果or_list大于一个元素,则形成一个Orcheck对象。

原理很简单:对于[ ["role:admin"], ["tenant_id:%(tenant_id)s"] ]情况,只需要满足内部一个条件即可, OrCheck。

而对于 ["role:admin", "tenant_id:%(tenant_id)s"] 这种情况,需要每一个都要满足,需要一个AndCheck。

def _parse_check(rule):

    # Handle the special checks
    if rule == '!':
        return FalseCheck()
    elif rule == '@':
        return TrueCheck()

    try:
        kind, match = rule.split(':', 1)
    except Exception:
        return FalseCheck()

    if kind in _checks:
        return _checks[kind](kind, match)
    elif None in _checks:
        return _checks[None](kind, match)
    else:
        return FalseCheck()
对于一个规则,rule:admin_or_owner, 拆分成kind(rule)与match(admin_or_owner),如果是'rule','role'等创建相应的对象,

如果没有匹配,则创建一个GenericCheck。

你可能感兴趣的:(Quantum的权限认证(3))