comparison test/rest_common.py @ 5879:94a7669677ae

add permissions to control user of rest and xmlrpc API interfaces. issue2551058: Add new permissions: 'Rest Access' and 'Xmlrpc Access' to allow per-user access control to rest and xmlrpc interfaces using roles. Updated all schemas to add these new perms to all authenticated roles. Error conditions in handle_xmlrpc were not working right in manual testing. I tried to make it a little better, but I don't actually understand how the fault xmlrpc object is supposed to be used. So I may have messed something up. I'll try to ping the people who wrote the xmlrpc code to have them review.
author John Rouillard <rouilj@ieee.org>
date Fri, 27 Sep 2019 23:29:59 -0400
parents 1b57d8f3eb97
children 5d0873a4de4a
comparison
equal deleted inserted replaced
5878:1b57d8f3eb97 5879:94a7669677ae
114 klass='user', 114 klass='user',
115 properties=('id', 'realname', 'address', 'username'), 115 properties=('id', 'realname', 'address', 'username'),
116 description="Allow jwt access to email", 116 description="Allow jwt access to email",
117 props_only=False) 117 props_only=False)
118 self.db.security.addPermissionToRole("User:email", jwt_perms) 118 self.db.security.addPermissionToRole("User:email", jwt_perms)
119 self.db.security.addPermissionToRole("User:email", "Rest Access")
120
121 # add set of roles for testing jwt's.
122 # this is like the user:email role, but it missing access to the rest endpoint.
123 self.db.security.addRole(name="User:emailnorest",
124 description="allow email by jwt")
125 jwt_perms = self.db.security.addPermission(name='View',
126 klass='user',
127 properties=('id', 'realname', 'address', 'username'),
128 description="Allow jwt access to email but forget to allow rest",
129 props_only=False)
130 self.db.security.addPermissionToRole("User:emailnorest", jwt_perms)
131
119 132
120 if jwt: 133 if jwt:
121 # must be 32 chars in length minimum (I think this is at least 134 # must be 32 chars in length minimum (I think this is at least
122 # 256 bits of data) 135 # 256 bits of data)
123 136
186 self.claim['user:email'] = copy(claim) 199 self.claim['user:email'] = copy(claim)
187 self.claim['user:email']['roles'] = [ "user:email" ] 200 self.claim['user:email']['roles'] = [ "user:email" ]
188 self.jwt['user:email'] = b2s(jwt.encode(self.claim['user:email'], secret, 201 self.jwt['user:email'] = b2s(jwt.encode(self.claim['user:email'], secret,
189 algorithm='HS256')) 202 algorithm='HS256'))
190 203
204 # generate valid claim with limited user:emailnorest role
205 self.claim['user:emailnorest'] = copy(claim)
206 self.claim['user:emailnorest']['roles'] = [ "user:emailnorest" ]
207 self.jwt['user:emailnorest'] = b2s(jwt.encode(self.claim['user:emailnorest'], secret,
208 algorithm='HS256'))
209
191 self.db.tx_Source = 'web' 210 self.db.tx_Source = 'web'
192 211
193 self.db.issue.addprop(tx_Source=hyperdb.String()) 212 self.db.issue.addprop(tx_Source=hyperdb.String())
194 self.db.issue.addprop(anint=hyperdb.Integer()) 213 self.db.issue.addprop(anint=hyperdb.Integer())
195 self.db.issue.addprop(afloat=hyperdb.Number()) 214 self.db.issue.addprop(afloat=hyperdb.Number())
3011 del(out[0]) 3030 del(out[0])
3012 self.db.setCurrentUser('admin') 3031 self.db.setCurrentUser('admin')
3013 3032
3014 @skip_jwt 3033 @skip_jwt
3015 def test_user_email_jwt(self): 3034 def test_user_email_jwt(self):
3035 '''tests "Rest Access" permission present case'''
3016 # self.dummy_client.main() closes database, so 3036 # self.dummy_client.main() closes database, so
3017 # we need a new test with setup called for each test 3037 # we need a new test with setup called for each test
3018 out = [] 3038 out = []
3019 def wh(s): 3039 def wh(s):
3020 out.append(s) 3040 out.append(s)
3076 # should have email addresses. Order is by id by default. 3096 # should have email addresses. Order is by id by default.
3077 self.assertTrue('address' in json_dict['data']['collection'][0]) 3097 self.assertTrue('address' in json_dict['data']['collection'][0])
3078 self.assertTrue('address' in json_dict['data']['collection'][1]) 3098 self.assertTrue('address' in json_dict['data']['collection'][1])
3079 self.assertTrue('address' in json_dict['data']['collection'][2]) 3099 self.assertTrue('address' in json_dict['data']['collection'][2])
3080 3100
3101 @skip_jwt
3102 def test_user_emailnorest_jwt(self):
3103 '''tests "Rest Access" permission missing case'''
3104 # self.dummy_client.main() closes database, so
3105 # we need a new test with setup called for each test
3106 out = []
3107 def wh(s):
3108 out.append(s)
3109
3110 secret = self.db.config.WEB_JWT_SECRET
3111
3112 # verify library and tokens are correct
3113 self.assertRaises(jwt.exceptions.InvalidTokenError,
3114 jwt.decode, self.jwt['expired'],
3115 secret, algorithms=['HS256'],
3116 audience=self.db.config.TRACKER_WEB,
3117 issuer=self.db.config.TRACKER_WEB)
3118
3119 result = jwt.decode(self.jwt['user'],
3120 secret, algorithms=['HS256'],
3121 audience=self.db.config.TRACKER_WEB,
3122 issuer=self.db.config.TRACKER_WEB)
3123 self.assertEqual(self.claim['user'],result)
3124
3125 result = jwt.decode(self.jwt['user:email'],
3126 secret, algorithms=['HS256'],
3127 audience=self.db.config.TRACKER_WEB,
3128 issuer=self.db.config.TRACKER_WEB)
3129 self.assertEqual(self.claim['user:email'],result)
3130
3131 # set environment for all jwt tests
3132 env = {
3133 'PATH_INFO': 'rest/data/user',
3134 'HTTP_HOST': 'localhost',
3135 'TRACKER_NAME': 'rounduptest',
3136 "REQUEST_METHOD": "GET"
3137 }
3138 self.dummy_client = client.Client(self.instance, MockNull(), env,
3139 [], None)
3140 self.dummy_client.db = self.db
3141 self.dummy_client.request.headers.get = self.get_header
3142 self.empty_form = cgi.FieldStorage()
3143 self.terse_form = cgi.FieldStorage()
3144 self.terse_form.list = [
3145 cgi.MiniFieldStorage('@verbose', '0'),
3146 ]
3147 self.dummy_client.form = cgi.FieldStorage()
3148 self.dummy_client.form.list = [
3149 cgi.MiniFieldStorage('@fields', 'username,address'),
3150 ]
3151 # accumulate json output for further analysis
3152 self.dummy_client.write = wh
3153
3154 # set up for limited user:email role token
3155 env['HTTP_AUTHORIZATION'] = 'bearer %s'%self.jwt['user:emailnorest']
3156 self.dummy_client.main()
3157 json_dict = json.loads(b2s(out[0]))
3158 # user will be joe id 3 as auth works
3159 self.assertTrue('1', self.db.getuid())
3160 { "error": { "status": 403, "msg": "Forbidden." } }
3161 self.assertTrue('error' in json_dict)
3162 self.assertTrue(json_dict['error']['status'], 403)
3163 self.assertTrue(json_dict['error']['msg'], "Forbidden.")
3081 3164
3082 @skip_jwt 3165 @skip_jwt
3083 def test_disabled_jwt(self): 3166 def test_disabled_jwt(self):
3084 # self.dummy_client.main() closes database, so 3167 # self.dummy_client.main() closes database, so
3085 # we need a new test with setup called for each test 3168 # we need a new test with setup called for each test

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