summaryrefslogtreecommitdiff
path: root/coip/apps/name/models.py
blob: d68b8bb71e5351248ff41e7d2aa808fbcf4a15ae (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
'''
Created on Jun 24, 2010

@author: leifj
'''
from django.db import models
import re
from twisted.python.reflect import ObjectNotFound
from pprint import pprint

class Attribute(models.Model):
    name = models.CharField(unique=True,max_length=255)
    description = models.TextField(blank=True)
    timecreated = models.DateTimeField(auto_now_add=True)
    lastupdated = models.DateTimeField(auto_now=True)
    
    def __unicode__(self):
        return self.name;

class Name(models.Model):
    '''
    A name-space/authorization/right/group/collaboration/thing
    '''
    type = models.ForeignKey(Attribute, blank=True, null=True,related_name='names')
    value = models.CharField(max_length=255)
    parent = models.ForeignKey('self', blank=True, null=True,related_name='children')
    partof = models.ForeignKey('self', blank=True, null=True,related_name='parts')
    acl = models.TextField(blank=True) # fully-qualified-name '#' rights
    short = models.CharField(max_length=64,blank=True)
    description = models.TextField(blank=True)
    timecreated = models.DateTimeField(auto_now_add=True)
    lastupdated = models.DateTimeField(auto_now=True)
    
    def shortname(self):
        if self.short:
            return self.short
        else:
            return self.__unicode__()
    
    def relative_name(self):
        if self.type:
            return "%s=%s" % (self.type.name,self.value)
        else:
            return self.value
    
    def __unicode__(self):
        n = self
        str = ""
        while n:
            sep = ""
            av = n.relative_name()
            
            if n.parent:
                if av.find("=") == -1:
                    sep = ':'
                else:
                    sep = ';'
                    
            str = sep+av+str
            n = n.parent
        
        return str
    
    def has_permission(self,user,perm):
        return True
    
    def permitted_children(self,user,perm):
        return filter(lambda s: s.has_permission(user,perm),self.children.all())
    
def roots():
    return Name.objects.filter(parent=None)
    
def _traverse(name,callable,user,depth):
    if not name:
        return [_traverse(s,callable,user,depth - 1) for s in roots()]
    else:
        t = callable(name,depth)
        if depth > 0:
            children = [_traverse(s,callable,user,depth - 1) for s in name.permitted_children(user,'#l')]
            if children:
                t['children'] = children 
        return t
    
def traverse(name,callable,user,depth,includeroot=False):
    if not name:
        return [_traverse(s,callable,user,depth - 1) for s in roots()]
    else:
        if includeroot:
            t = callable(name,depth)
            if depth > 0:
                children = [_traverse(s,callable,user,depth - 1) for s in name.permitted_children(user,'#l')]
                if children:
                    t['children'] = children
            return t
        else:
            return [_traverse(s,callable,user,depth - 1) for s in name.permitted_children(user,'#l')]
    
def walkto(root,nameparts,autocreate=False,autoacl='#l'):
    name = None
    for n in nameparts:
        (a,eq,v) = n.partition('=')
        if v:
            attribute = Attribute.objects.get(name=a)
            try:
                name = Name.objects.get(parent=root,type=attribute.id,value=v)
            except ObjectNotFound,e:
                if autocreate:
                    name = Name.objects.create(parent=root,type=attribute.id,value=v,acl=autoacl)
                else:
                    raise e
        else:
            try:
                name = Name.objects.get(parent=root,type=None,value=a)
            except ObjectNotFound,e:
                if autocreate:
                    name = Name.objects.create(parent=root,type=None,value=a,acl=autoacl)
                else:
                    raise e
    return name

def lookup(name,autocreate=False,autoacl='#l'):
    return walkto(None,nameparts=re.compile('[;:]').split(name),autocreate=autocreate,autoacl=autoacl)

def attribute(a):
    Attribute.objects.get_or_create(name=a)