Mercurial > p > roundup > code
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 } |
