Quantum的权限认证(3)

来源:互联网 发布:信息推广软件 编辑:程序博客网 时间:2024/06/07 22:59

本文地址: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。

原创粉丝点击