index aab6a95fb5ac30883d44bb54689a3d0eddeeee42..a403481864364642d7a03072f332ee334593f6d9 100644 (file)
c['context'] = HTMLItem(client, classname, client.nodeid,
anonymous=1)
elif client.db.classes.has_key(classname):
c['context'] = HTMLItem(client, classname, client.nodeid,
anonymous=1)
elif client.db.classes.has_key(classname):
- c['context'] = HTMLClass(client, classname, anonymous=1)
+ if classname == 'user':
+ c['context'] = HTMLUserClass(client, classname, anonymous=1)
+ else:
+ c['context'] = HTMLClass(client, classname, anonymous=1)
return c
def render(self, client, classname, request, **options):
return c
def render(self, client, classname, request, **options):
return HTMLItem(self._client, m.group('cl'), m.group('id'))
else:
self._client.db.getclass(item)
return HTMLItem(self._client, m.group('cl'), m.group('id'))
else:
self._client.db.getclass(item)
+ if item == 'user':
+ return HTMLUserClass(self._client, item)
return HTMLClass(self._client, item)
def __getattr__(self, attr):
return HTMLClass(self._client, item)
def __getattr__(self, attr):
def classes(self):
l = self._client.db.classes.keys()
l.sort()
def classes(self):
l = self._client.db.classes.keys()
l.sort()
- return [HTMLClass(self._client, cn) for cn in l]
-
-def lookupIds(db, prop, ids, num_re=re.compile('-?\d+')):
+ r = []
+ for item in l:
+ if item == 'user':
+ m.append(HTMLUserClass(self._client, item))
+ m.append(HTMLClass(self._client, item))
+ return r
+
+def lookupIds(db, prop, ids, fail_ok=0, num_re=re.compile('-?\d+')):
+ ''' "fail_ok" should be specified if we wish to pass through bad values
+ (most likely form values that we wish to represent back to the user)
+ '''
cl = db.getclass(prop.classname)
l = []
for entry in ids:
cl = db.getclass(prop.classname)
l = []
for entry in ids:
else:
try:
l.append(cl.lookup(entry))
else:
try:
l.append(cl.lookup(entry))
- except KeyError:
- # ignore invalid keys
- pass
+ except (TypeError, KeyError):
+ if fail_ok:
+ # pass through the bad value
+ l.append(entry)
+ return l
+
+def lookupKeys(linkcl, key, ids, num_re=re.compile('-?\d+')):
+ ''' Look up the "key" values for "ids" list - though some may already
+ be key values, not ids.
+ '''
+ l = []
+ for entry in ids:
+ if num_re.match(entry):
+ l.append(linkcl.get(entry, key))
+ else:
+ l.append(entry)
return l
class HTMLPermissions:
return l
class HTMLPermissions:
return None
# get the property
return None
# get the property
- prop = self._props[item]
+ try:
+ prop = self._props[item]
+ except KeyError:
+ raise KeyError, 'No such property "%s" on %s'%(item, self.classname)
# look up the correct HTMLProperty class
form = self._client.form
# look up the correct HTMLProperty class
form = self._client.form
if form.has_key(item):
if isinstance(prop, hyperdb.Multilink):
value = lookupIds(self._db, prop,
if form.has_key(item):
if isinstance(prop, hyperdb.Multilink):
value = lookupIds(self._db, prop,
- handleListCGIValue(form[item]))
+ handleListCGIValue(form[item]), fail_ok=1)
elif isinstance(prop, hyperdb.Link):
value = form[item].value.strip()
if value:
elif isinstance(prop, hyperdb.Link):
value = form[item].value.strip()
if value:
- value = lookupIds(self._db, prop, [value])[0]
+ value = lookupIds(self._db, prop, [value],
+ fail_ok=1)[0]
else:
value = None
else:
else:
value = None
else:
''' Get an item of this class by its item id.
'''
# make sure we're looking at an itemid
''' Get an item of this class by its item id.
'''
# make sure we're looking at an itemid
- if not num_re.match(itemid):
+ if not isinstance(itemid, type(1)) and not num_re.match(itemid):
itemid = self._klass.lookup(itemid)
if self.classname == 'user':
itemid = self._klass.lookup(itemid)
if self.classname == 'user':
raise AttributeError, attr
def designator(self):
raise AttributeError, attr
def designator(self):
- ''' Return this item's designator (classname + id) '''
+ """Return this item's designator (classname + id)."""
return '%s%s'%(self._classname, self._nodeid)
def submit(self, label="Submit Changes"):
return '%s%s'%(self._classname, self._nodeid)
def submit(self, label="Submit Changes"):
- ''' Generate a submit button (and action hidden element)
- '''
- return self.input(type="hidden",name="@action",value="edit") + '\n' + \
- self.input(type="submit",name="submit",value=label)
+ """Generate a submit button.
+
+ Also sneak in the lastactivity and action hidden elements.
+ """
+ return self.input(type="hidden", name="@lastactivity", value=date.Date('.')) + '\n' + \
+ self.input(type="hidden", name="@action", value="edit") + '\n' + \
+ self.input(type="submit", name="submit", value=label)
def journal(self, direction='descending'):
''' Return a list of HTMLJournalEntry instances.
def journal(self, direction='descending'):
''' Return a list of HTMLJournalEntry instances.
# use our fabricated request
return pt.render(self._client, req.classname, req)
# use our fabricated request
return pt.render(self._client, req.classname, req)
-class HTMLUser(HTMLItem):
+class HTMLUserPermission:
+
+ def is_edit_ok(self):
+ ''' Is the user allowed to Edit the current class?
+ Also check whether this is the current user's info.
+ '''
+ return self._user_perm_check('Edit')
+
+ def is_view_ok(self):
+ ''' Is the user allowed to View the current class?
+ Also check whether this is the current user's info.
+ '''
+ return self._user_perm_check('View')
+
+ def _user_perm_check(self, type):
+ # some users may view / edit all users
+ s = self._db.security
+ userid = self._client.userid
+ if s.hasPermission(type, userid, self._classname):
+ return 1
+
+ # users may view their own info
+ is_anonymous = self._db.user.get(userid, 'username') == 'anonymous'
+ if getattr(self, '_nodeid', None) == userid and not is_anonymous:
+ return 1
+
+ # may anonymous users register?
+ if (is_anonymous and s.hasPermission('Web Registration', userid,
+ self._classname)):
+ return 1
+
+ # nope, no access here
+ return 0
+
+class HTMLUserClass(HTMLUserPermission, HTMLClass):
+ pass
+
+class HTMLUser(HTMLUserPermission, HTMLItem):
''' Accesses through the *user* (a special case of item)
'''
def __init__(self, client, classname, nodeid, anonymous=0):
''' Accesses through the *user* (a special case of item)
'''
def __init__(self, client, classname, nodeid, anonymous=0):
classname = self._default_classname
return self._security.hasPermission(permission, self._nodeid, classname)
classname = self._default_classname
return self._security.hasPermission(permission, self._nodeid, classname)
- def is_edit_ok(self):
- ''' Is the user allowed to Edit the current class?
- Also check whether this is the current user's info.
- '''
- return self._db.security.hasPermission('Edit', self._client.userid,
- self._classname) or (self._nodeid == self._client.userid and
- self._db.user.get(self._client.userid, 'username') != 'anonymous')
-
- def is_view_ok(self):
- ''' Is the user allowed to View the current class?
- Also check whether this is the current user's info.
- '''
- return self._db.security.hasPermission('View', self._client.userid,
- self._classname) or (self._nodeid == self._client.userid and
- self._db.user.get(self._client.userid, 'username') != 'anonymous')
-
class HTMLProperty(HTMLInputMixin, HTMLPermissions):
''' String, Number, Date, Interval HTMLProperty
class HTMLProperty(HTMLInputMixin, HTMLPermissions):
''' String, Number, Date, Interval HTMLProperty
s2 = match.group('id')
try:
# make sure s1 is a valid tracker classname
s2 = match.group('id')
try:
# make sure s1 is a valid tracker classname
- self._db.getclass(s1)
- return '<a href="%s">%s %s</a>'%(s, s1, s2)
+ cl = self._db.getclass(s1)
+ if not cl.hasnode(s2):
+ raise KeyError, 'oops'
+ return '<a href="%s">%s%s</a>'%(s, s1, s2)
except KeyError:
return '%s%s'%(s1, s2)
except KeyError:
return '%s%s'%(s1, s2)
'''
self.view_check()
'''
self.view_check()
- return DateHTMLProperty(self._client, self._nodeid, self._prop,
- self._formname, date.Date('.'))
+ return DateHTMLProperty(self._client, self._classname, self._nodeid,
+ self._prop, self._formname, date.Date('.'))
def field(self, size = 30):
''' Render a form edit field for the property
def field(self, size = 30):
''' Render a form edit field for the property
'''
self.view_check()
'''
self.view_check()
- return DateHTMLProperty(self._client, self._nodeid, self._prop,
- self._formname, self._value.local(offset))
+ return DateHTMLProperty(self._client, self._classname, self._nodeid,
+ self._prop, self._formname, self._value.local(offset))
class IntervalHTMLProperty(HTMLProperty):
def plain(self):
class IntervalHTMLProperty(HTMLProperty):
def plain(self):
showid=1
if not showid:
k = linkcl.labelprop(1)
showid=1
if not showid:
k = linkcl.labelprop(1)
- value = [linkcl.get(v, k) for v in value]
+ value = lookupKeys(linkcl, k, value)
value = cgi.escape(','.join(value))
return self.input(name=self._formname,size=size,value=value)
value = cgi.escape(','.join(value))
return self.input(name=self._formname,size=size,value=value)