comparison roundup/rest.py @ 5678:b8e8b1b3ec77

REST: Add key lookup E.g. /data/status/open or /data/status/name=open Also update documentation and tests
author Ralf Schlatterbeck <rsc@runtux.com>
date Thu, 28 Mar 2019 12:21:40 +0100
parents 1fa59181ce58
children df9eb574b717
comparison
equal deleted inserted replaced
5677:1fa59181ce58 5678:b8e8b1b3ec77
603 class_name and item_id should be valid already 603 class_name and item_id should be valid already
604 604
605 Args: 605 Args:
606 class_name (string): class name of the resource (Ex: issue, msg) 606 class_name (string): class name of the resource (Ex: issue, msg)
607 item_id (string): id of the resource (Ex: 12, 15) 607 item_id (string): id of the resource (Ex: 12, 15)
608 or (if the class has a key property) this can also be
609 the key name, e.g. class_name = status, item_id = 'open'
608 input (list): the submitted form of the user 610 input (list): the submitted form of the user
609 611
610 Returns: 612 Returns:
611 int: http status code 200 (OK) 613 int: http status code 200 (OK)
612 dict: a dictionary represents the object 614 dict: a dictionary represents the object
615 link: link to the object 617 link: link to the object
616 attributes: a dictionary represent the attributes of the object 618 attributes: a dictionary represent the attributes of the object
617 """ 619 """
618 if class_name not in self.db.classes: 620 if class_name not in self.db.classes:
619 raise NotFound('Class %s not found' % class_name) 621 raise NotFound('Class %s not found' % class_name)
622 class_obj = self.db.getclass(class_name)
623 uid = self.db.getuid()
624 # If it's not numeric it is a key
625 if item_id.isdigit():
626 id = item_id
627 else:
628 keyprop = class_obj.getkey()
629 try:
630 k, v = item_id.split('=', 1)
631 if k != keyprop:
632 raise UsageError ("Not key property")
633 except ValueError:
634 v = item_id
635 pass
636 if not self.db.security.hasPermission(
637 'View', uid, class_name, itemid=item_id, property=keyprop
638 ):
639 raise Unauthorised(
640 'Permission to view %s%s.%s denied'
641 % (class_name, item_id, keyprop)
642 )
643 id = class_obj.lookup(v)
620 if not self.db.security.hasPermission( 644 if not self.db.security.hasPermission(
621 'View', self.db.getuid(), class_name, itemid=item_id 645 'View', uid, class_name, itemid=id
622 ): 646 ):
623 raise Unauthorised( 647 raise Unauthorised(
624 'Permission to view %s%s denied' % (class_name, item_id) 648 'Permission to view %s%s denied' % (class_name, id)
625 ) 649 )
626 650
627 class_obj = self.db.getclass(class_name) 651 node = class_obj.getnode(id)
628 node = class_obj.getnode(item_id) 652 etag = calculate_etag(node, class_name, id)
629 etag = calculate_etag(node, class_name, item_id)
630 props = None 653 props = None
631 protected=False 654 protected=False
632 verbose=1 655 verbose=1
633 for form_field in input.value: 656 for form_field in input.value:
634 key = form_field.name 657 key = form_field.name
649 672
650 try: 673 try:
651 for pn in sorted(props): 674 for pn in sorted(props):
652 prop = props[pn] 675 prop = props[pn]
653 if not self.db.security.hasPermission( 676 if not self.db.security.hasPermission(
654 'View', uid, class_name, pn, item_id 677 'View', uid, class_name, pn, id
655 ): 678 ):
656 continue 679 continue
657 v = getattr(node, pn) 680 v = getattr(node, pn)
658 if isinstance (prop, (hyperdb.Link, hyperdb.Multilink)): 681 if isinstance (prop, (hyperdb.Link, hyperdb.Multilink)):
659 linkcls = self.db.getclass (prop.classname) 682 linkcls = self.db.getclass (prop.classname)
688 else: 711 else:
689 result[pn] = v 712 result[pn] = v
690 except KeyError as msg: 713 except KeyError as msg:
691 raise UsageError("%s field not valid" % msg) 714 raise UsageError("%s field not valid" % msg)
692 result = { 715 result = {
693 'id': item_id, 716 'id': id,
694 'type': class_name, 717 'type': class_name,
695 'link': '%s/%s/%s' % (self.data_path, class_name, item_id), 718 'link': '%s/%s/%s' % (self.data_path, class_name, item_id),
696 'attributes': dict(result), 719 'attributes': dict(result),
697 '@etag': etag 720 '@etag': etag
698 } 721 }

Roundup Issue Tracker: http://roundup-tracker.org/