comparison doc/rest.txt @ 5892:afb5705d1fe5

Updates to jwt permissions; typo fixes Clarified that some View access is needed to the issue class. At minimum depending on how the update is done the etag of the issue is required. Also noted that returned json does include new value of the field. So this could leak info.
author John Rouillard <rouilj@ieee.org>
date Wed, 02 Oct 2019 20:42:08 -0400
parents ed18adf8a006
children 13f5ac918120
comparison
equal deleted inserted replaced
5891:6e341009593b 5892:afb5705d1fe5
680 By default all (visible to the current user) attributes/properties are 680 By default all (visible to the current user) attributes/properties are
681 returned. You can limit this by using the ``@fields`` query parameter 681 returned. You can limit this by using the ``@fields`` query parameter
682 similar to how it is used in collections. This way you can only return 682 similar to how it is used in collections. This way you can only return
683 the fields you are interested in reducing network load as well as 683 the fields you are interested in reducing network load as well as
684 memory and parsing time on the client side. By default protected 684 memory and parsing time on the client side. By default protected
685 properties (read only in the database) are not listed. Th 685 properties (read only in the database) are not listed. This
686 is makes it easier to submit the attributes from a 686 makes it easier to submit the attributes from a
687 ``@verbose=0`` query using PUT. To include protected properties 687 ``@verbose=0`` query using PUT. To include protected properties
688 in the output of a GET add the query parameter 688 in the output of a GET add the query parameter
689 ``@protected=true`` to the query and attributes like: actor, 689 ``@protected=true`` to the query and attributes like: actor,
690 created, creator and activity will be include in the result. 690 created, creator and activity will be include in the result.
691 691
860 curl -u admin:admin ... 860 curl -u admin:admin ...
861 --data '{ "nosy": [ "4", "5" ], "title": "...", "@pretty": "false" }' 861 --data '{ "nosy": [ "4", "5" ], "title": "...", "@pretty": "false" }'
862 862
863 produces:: 863 produces::
864 864
865 {"data": {"attribute": {}, "type": "issue", 865 {"data": {"attribute": {...}, "type": "issue",
866 "link": "https://...", "id": "23"}} 866 "link": "https://...", "id": "23"}}
867 867
868 the lines are wrapped for display purposes, in real life it's one long 868 the lines are wrapped for display purposes, in real life it's one long
869 line. 869 line.
870 870
1399 username and credentials. Especially if your roundup instance is under 1399 username and credentials. Especially if your roundup instance is under
1400 your company's single sign on infrastructure. 1400 your company's single sign on infrastructure.
1401 1401
1402 So what we need is a way for this third part service to impersonate 1402 So what we need is a way for this third part service to impersonate
1403 you and have access to create a roundup timelog entry (see 1403 you and have access to create a roundup timelog entry (see
1404 `<customizing.html#adding-a-time-log-to-your-issues>`__. Then add it 1404 `<customizing.html#adding-a-time-log-to-your-issues>`__). Then add it
1405 to the associated issue. This should happen without sharing passwords 1405 to the associated issue. This should happen without sharing passwords
1406 and without the third party service to see the issue (except the 1406 and without the third party service to see the issue (except the
1407 ``times`` property), user, or other information in the tracker. 1407 ``times`` property), user, or other information in the tracker.
1408 1408
1409 Enter the use of a JSON web token. Roundup has rudimentary ability to 1409 Enter the use of a JSON web token. Roundup has rudimentary ability to
1411 1411
1412 There are 5 steps to set this up: 1412 There are 5 steps to set this up:
1413 1413
1414 1. install pyjwt library using pip or pip3. If roundup can't find the 1414 1. install pyjwt library using pip or pip3. If roundup can't find the
1415 jwt module you will see the error ``Support for jwt disabled.`` 1415 jwt module you will see the error ``Support for jwt disabled.``
1416 2. create a new role that allows Create access to timelog and edit 1416 2. create a new role that allows Create access to timelog and edit/view
1417 access to an issues' ``times`` property. 1417 access to an issues' ``times`` property.
1418 3. add support for issuing (and validating) jwts to the rest interface. 1418 3. add support for issuing (and validating) jwts to the rest interface.
1419 This uses the `Adding new rest endpoints`_ mechanism. 1419 This uses the `Adding new rest endpoints`_ mechanism.
1420 4. configure roundup's config.ini [web] jwt_secret with at least 32 1420 4. configure roundup's config.ini [web] jwt_secret with at least 32
1421 random characters of data. (You will get a message 1421 random characters of data. (You will get a message
1422 ``Support for jwt disabled by admin.`` if it's not long enough.) 1422 ``Support for jwt disabled by admin.`` if it's not long enough.)
1423 5. add an auditor to make sure that users with this role are appending 1423 5. add an auditor to make sure that users with this role are appending
1424 timelog links to the `times` property of the issue. 1424 timelog links to the ``times`` property of the issue.
1425 1425
1426 Create role 1426 Create role
1427 """"""""""" 1427 """""""""""
1428 1428
1429 Adding this snippet of code to the tracker's ``schema.py`` should create a role with the 1429 Adding this snippet of code to the tracker's ``schema.py`` should create a role with the
1430 proper authorization:: 1430 proper authorization::
1431 1431
1432 db.security.addRole(name="User:timelog", description="allow a user to create and append timelogs") 1432 db.security.addRole(name="User:timelog",
1433 description="allow a user to create and append timelogs")
1434
1435 db.security.addPermissionToRole('User:timelog', 'Rest Access')
1436
1433 perm = db.security.addPermission(name='Create', klass='timelog', 1437 perm = db.security.addPermission(name='Create', klass='timelog',
1434 description="Allow timelog creation", props_only=False) 1438 description="Allow timelog creation", props_only=False)
1435 db.security.addPermissionToRole("User:timelog", perm) 1439 db.security.addPermissionToRole("User:timelog", perm)
1440
1441 perm = db.security.addPermission(name='View', klass='issue',
1442 properties=('id', 'times'),
1443 description="Allow timelog retreival for issue",
1444 props_only=False)
1445 db.security.addPermissionToRole("User:timelog", perm)
1446
1436 perm = db.security.addPermission(name='Edit', klass='issue', 1447 perm = db.security.addPermission(name='Edit', klass='issue',
1437 properties=('id', 'times'), 1448 properties=('id', 'times'),
1438 description="Allow editing timelog for issue", props_only=False) 1449 description="Allow editing timelog for issue", props_only=False)
1439 db.security.addPermissionToRole("User:timelog", perm) 1450 db.security.addPermissionToRole("User:timelog", perm)
1440 db.security.addPermissionToRole('User:timelog', 'Rest Access') 1451
1441 1452 The role is named to work with the /rest/jwt/issue rest endpoint
1442 Then role is named to work with the jwt issue rest call. Starting the role 1453 defined below. Starting the role name with ``User:`` allows the jwt
1443 name with ``User:`` allows the jwt issue code to create a token with 1454 issue code to create a token with this role if the user requesting the
1444 this role if the user requesting the role has the User role. 1455 role has the User role.
1456
1457 The role *must* have access to the issue ``id`` to retrieve the etag for
1458 the issue. The etag is passed in the ``If-Match`` HTTP header when you
1459 make a call to patch or update the ``timess` property of the issue.
1460
1461 If you use a PATCH rest call with "@op=add" to append the new timelog,
1462 you don't need View access to the ``times`` property. If you replace the
1463 ``times`` value, you need to read the current value of ``times`` (using
1464 View permission), append the newly created timelog id to the (array)
1465 value, and replace the ``times`` value.
1466
1467 Note that the json returned after the operation will include the new
1468 value of the ``times`` value so your code can verify that it worked.
1469 This does potentially leak info about the previous id's in the field.
1445 1470
1446 Create rest endpoints 1471 Create rest endpoints
1447 """"""""""""""""""""" 1472 """""""""""""""""""""
1448 1473
1449 Here is code to add to your tracker's ``interfaces.py`` (note code is 1474 Here is code to add to your tracker's ``interfaces.py`` (note code has
1450 python3):: 1475 only been tested with python3)::
1451 1476
1452 from roundup.rest import Routing, RestfulInstance, _data_decorator 1477 from roundup.rest import Routing, RestfulInstance, _data_decorator
1453 1478
1454 class RestfulInstance(object): 1479 class RestfulInstance(object):
1455 @Routing.route("/jwt/issue", 'POST') 1480 @Routing.route("/jwt/issue", 'POST')

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