]>
git.proxmox.com Git - ceph.git/blob - ceph/qa/tasks/mgr/dashboard/test_auth.py
1 # -*- coding: utf-8 -*-
3 from __future__
import absolute_import
8 from teuthology
.orchestra
.run
import \
9 CommandFailedError
# pylint: disable=import-error
11 from .helper
import DashboardTestCase
, JLeaf
, JObj
14 class AuthTest(DashboardTestCase
):
16 AUTO_AUTHENTICATE
= False
19 super(AuthTest
, self
).setUp()
22 def _validate_jwt_token(self
, token
, username
, permissions
):
23 payload
= jwt
.decode(token
, options
={'verify_signature': False})
24 self
.assertIn('username', payload
)
25 self
.assertEqual(payload
['username'], username
)
27 for scope
, perms
in permissions
.items():
28 self
.assertIsNotNone(scope
)
29 self
.assertIn('read', perms
)
30 self
.assertIn('update', perms
)
31 self
.assertIn('create', perms
)
32 self
.assertIn('delete', perms
)
34 def test_login_without_password(self
):
35 with self
.assertRaises(CommandFailedError
):
36 self
.create_user('admin2', '', ['administrator'], force_password
=True)
38 def test_a_set_login_credentials(self
):
39 # test with Authorization header
40 self
.create_user('admin2', 'admin2', ['administrator'])
41 self
._post
("/api/auth", {'username': 'admin2', 'password': 'admin2'})
42 self
.assertStatus(201)
43 data
= self
.jsonBody()
44 self
._validate
_jwt
_token
(data
['token'], "admin2", data
['permissions'])
45 self
.delete_user('admin2')
47 # test with Cookies set
48 self
.create_user('admin2', 'admin2', ['administrator'])
49 self
._post
("/api/auth", {'username': 'admin2', 'password': 'admin2'}, set_cookies
=True)
50 self
.assertStatus(201)
51 data
= self
.jsonBody()
52 self
._validate
_jwt
_token
(data
['token'], "admin2", data
['permissions'])
53 self
.delete_user('admin2')
55 def test_login_valid(self
):
56 # test with Authorization header
57 self
._post
("/api/auth", {'username': 'admin', 'password': 'admin'})
58 self
.assertStatus(201)
59 data
= self
.jsonBody()
60 self
.assertSchema(data
, JObj(sub_elems
={
62 'username': JLeaf(str),
63 'permissions': JObj(sub_elems
={}, allow_unknown
=True),
65 'pwdExpirationDate': JLeaf(int, none
=True),
66 'pwdUpdateRequired': JLeaf(bool)
67 }, allow_unknown
=False))
68 self
._validate
_jwt
_token
(data
['token'], "admin", data
['permissions'])
70 # test with Cookies set
71 self
._post
("/api/auth", {'username': 'admin', 'password': 'admin'}, set_cookies
=True)
72 self
.assertStatus(201)
73 data
= self
.jsonBody()
74 self
.assertSchema(data
, JObj(sub_elems
={
76 'username': JLeaf(str),
77 'permissions': JObj(sub_elems
={}, allow_unknown
=True),
79 'pwdExpirationDate': JLeaf(int, none
=True),
80 'pwdUpdateRequired': JLeaf(bool)
81 }, allow_unknown
=False))
82 self
._validate
_jwt
_token
(data
['token'], "admin", data
['permissions'])
84 def test_login_invalid(self
):
85 # test with Authorization header
86 self
._post
("/api/auth", {'username': 'admin', 'password': 'inval'})
87 self
.assertStatus(400)
90 "code": "invalid_credentials",
91 "detail": "Invalid credentials"
94 def test_lockout_user(self
):
95 # test with Authorization header
96 self
._ceph
_cmd
(['dashboard', 'set-account-lockout-attempts', '3'])
98 self
._post
("/api/auth", {'username': 'admin', 'password': 'inval'})
99 self
._post
("/api/auth", {'username': 'admin', 'password': 'admin'})
100 self
.assertStatus(400)
101 self
.assertJsonBody({
103 "code": "invalid_credentials",
104 "detail": "Invalid credentials"
106 self
._ceph
_cmd
(['dashboard', 'ac-user-enable', 'admin'])
107 self
._post
("/api/auth", {'username': 'admin', 'password': 'admin'})
108 self
.assertStatus(201)
109 data
= self
.jsonBody()
110 self
.assertSchema(data
, JObj(sub_elems
={
112 'username': JLeaf(str),
113 'permissions': JObj(sub_elems
={}, allow_unknown
=True),
115 'pwdExpirationDate': JLeaf(int, none
=True),
116 'pwdUpdateRequired': JLeaf(bool)
117 }, allow_unknown
=False))
118 self
._validate
_jwt
_token
(data
['token'], "admin", data
['permissions'])
120 # test with Cookies set
121 self
._ceph
_cmd
(['dashboard', 'set-account-lockout-attempts', '3'])
123 self
._post
("/api/auth", {'username': 'admin', 'password': 'inval'}, set_cookies
=True)
124 self
._post
("/api/auth", {'username': 'admin', 'password': 'admin'}, set_cookies
=True)
125 self
.assertStatus(400)
126 self
.assertJsonBody({
128 "code": "invalid_credentials",
129 "detail": "Invalid credentials"
131 self
._ceph
_cmd
(['dashboard', 'ac-user-enable', 'admin'])
132 self
._post
("/api/auth", {'username': 'admin', 'password': 'admin'}, set_cookies
=True)
133 self
.assertStatus(201)
134 data
= self
.jsonBody()
135 self
.assertSchema(data
, JObj(sub_elems
={
137 'username': JLeaf(str),
138 'permissions': JObj(sub_elems
={}, allow_unknown
=True),
140 'pwdExpirationDate': JLeaf(int, none
=True),
141 'pwdUpdateRequired': JLeaf(bool)
142 }, allow_unknown
=False))
143 self
._validate
_jwt
_token
(data
['token'], "admin", data
['permissions'])
145 def test_logout(self
):
146 # test with Authorization header
147 self
._post
("/api/auth", {'username': 'admin', 'password': 'admin'})
148 self
.assertStatus(201)
149 data
= self
.jsonBody()
150 self
._validate
_jwt
_token
(data
['token'], "admin", data
['permissions'])
151 self
.set_jwt_token(data
['token'])
152 self
._post
("/api/auth/logout")
153 self
.assertStatus(200)
154 self
.assertJsonBody({
155 "redirect_url": "#/login"
157 self
._get
("/api/host", version
='1.1')
158 self
.assertStatus(401)
159 self
.set_jwt_token(None)
161 # test with Cookies set
162 self
._post
("/api/auth", {'username': 'admin', 'password': 'admin'}, set_cookies
=True)
163 self
.assertStatus(201)
164 data
= self
.jsonBody()
165 self
._validate
_jwt
_token
(data
['token'], "admin", data
['permissions'])
166 self
.set_jwt_token(data
['token'])
167 self
._post
("/api/auth/logout", set_cookies
=True)
168 self
.assertStatus(200)
169 self
.assertJsonBody({
170 "redirect_url": "#/login"
172 self
._get
("/api/host", set_cookies
=True, version
='1.1')
173 self
.assertStatus(401)
174 self
.set_jwt_token(None)
176 def test_token_ttl(self
):
177 # test with Authorization header
178 self
._ceph
_cmd
(['dashboard', 'set-jwt-token-ttl', '5'])
179 self
._post
("/api/auth", {'username': 'admin', 'password': 'admin'})
180 self
.assertStatus(201)
181 self
.set_jwt_token(self
.jsonBody()['token'])
182 self
._get
("/api/host", version
='1.1')
183 self
.assertStatus(200)
185 self
._get
("/api/host", version
='1.1')
186 self
.assertStatus(401)
187 self
._ceph
_cmd
(['dashboard', 'set-jwt-token-ttl', '28800'])
188 self
.set_jwt_token(None)
190 # test with Cookies set
191 self
._ceph
_cmd
(['dashboard', 'set-jwt-token-ttl', '5'])
192 self
._post
("/api/auth", {'username': 'admin', 'password': 'admin'}, set_cookies
=True)
193 self
.assertStatus(201)
194 self
.set_jwt_token(self
.jsonBody()['token'])
195 self
._get
("/api/host", set_cookies
=True, version
='1.1')
196 self
.assertStatus(200)
198 self
._get
("/api/host", set_cookies
=True, version
='1.1')
199 self
.assertStatus(401)
200 self
._ceph
_cmd
(['dashboard', 'set-jwt-token-ttl', '28800'])
201 self
.set_jwt_token(None)
203 def test_remove_from_blocklist(self
):
204 # test with Authorization header
205 self
._ceph
_cmd
(['dashboard', 'set-jwt-token-ttl', '5'])
206 self
._post
("/api/auth", {'username': 'admin', 'password': 'admin'})
207 self
.assertStatus(201)
208 self
.set_jwt_token(self
.jsonBody()['token'])
209 # the following call adds the token to the blocklist
210 self
._post
("/api/auth/logout")
211 self
.assertStatus(200)
212 self
._get
("/api/host", version
='1.1')
213 self
.assertStatus(401)
215 self
._ceph
_cmd
(['dashboard', 'set-jwt-token-ttl', '28800'])
216 self
.set_jwt_token(None)
217 self
._post
("/api/auth", {'username': 'admin', 'password': 'admin'})
218 self
.assertStatus(201)
219 self
.set_jwt_token(self
.jsonBody()['token'])
220 # the following call removes expired tokens from the blocklist
221 self
._post
("/api/auth/logout")
222 self
.assertStatus(200)
224 # test with Cookies set
225 self
._ceph
_cmd
(['dashboard', 'set-jwt-token-ttl', '5'])
226 self
._post
("/api/auth", {'username': 'admin', 'password': 'admin'}, set_cookies
=True)
227 self
.assertStatus(201)
228 self
.set_jwt_token(self
.jsonBody()['token'])
229 # the following call adds the token to the blocklist
230 self
._post
("/api/auth/logout", set_cookies
=True)
231 self
.assertStatus(200)
232 self
._get
("/api/host", set_cookies
=True, version
='1.1')
233 self
.assertStatus(401)
235 self
._ceph
_cmd
(['dashboard', 'set-jwt-token-ttl', '28800'])
236 self
.set_jwt_token(None)
237 self
._post
("/api/auth", {'username': 'admin', 'password': 'admin'}, set_cookies
=True)
238 self
.assertStatus(201)
239 self
.set_jwt_token(self
.jsonBody()['token'])
240 # the following call removes expired tokens from the blocklist
241 self
._post
("/api/auth/logout", set_cookies
=True)
242 self
.assertStatus(200)
244 def test_unauthorized(self
):
245 # test with Authorization header
246 self
._get
("/api/host", version
='1.1')
247 self
.assertStatus(401)
249 # test with Cookies set
250 self
._get
("/api/host", set_cookies
=True, version
='1.1')
251 self
.assertStatus(401)
253 def test_invalidate_token_by_admin(self
):
254 # test with Authorization header
255 self
._get
("/api/host", version
='1.1')
256 self
.assertStatus(401)
257 self
.create_user('user', 'user', ['read-only'])
259 self
._post
("/api/auth", {'username': 'user', 'password': 'user'})
260 self
.assertStatus(201)
261 self
.set_jwt_token(self
.jsonBody()['token'])
262 self
._get
("/api/host", version
='1.1')
263 self
.assertStatus(200)
265 self
._ceph
_cmd
_with
_secret
(['dashboard', 'ac-user-set-password', '--force-password',
269 self
._get
("/api/host", version
='1.1')
270 self
.assertStatus(401)
271 self
.set_jwt_token(None)
272 self
._post
("/api/auth", {'username': 'user', 'password': 'user2'})
273 self
.assertStatus(201)
274 self
.set_jwt_token(self
.jsonBody()['token'])
275 self
._get
("/api/host", version
='1.1')
276 self
.assertStatus(200)
277 self
.delete_user("user")
279 # test with Cookies set
280 self
._get
("/api/host", set_cookies
=True, version
='1.1')
281 self
.assertStatus(401)
282 self
.create_user('user', 'user', ['read-only'])
284 self
._post
("/api/auth", {'username': 'user', 'password': 'user'}, set_cookies
=True)
285 self
.assertStatus(201)
286 self
.set_jwt_token(self
.jsonBody()['token'])
287 self
._get
("/api/host", set_cookies
=True, version
='1.1')
288 self
.assertStatus(200)
290 self
._ceph
_cmd
_with
_secret
(['dashboard', 'ac-user-set-password', '--force-password',
294 self
._get
("/api/host", set_cookies
=True, version
='1.1')
295 self
.assertStatus(401)
296 self
.set_jwt_token(None)
297 self
._post
("/api/auth", {'username': 'user', 'password': 'user2'}, set_cookies
=True)
298 self
.assertStatus(201)
299 self
.set_jwt_token(self
.jsonBody()['token'])
300 self
._get
("/api/host", set_cookies
=True, version
='1.1')
301 self
.assertStatus(200)
302 self
.delete_user("user")
304 def test_check_token(self
):
305 # test with Authorization header
306 self
.login("admin", "admin")
307 self
._post
("/api/auth/check", {"token": self
.jsonBody()["token"]})
308 self
.assertStatus(200)
309 data
= self
.jsonBody()
310 self
.assertSchema(data
, JObj(sub_elems
={
311 "username": JLeaf(str),
312 "permissions": JObj(sub_elems
={}, allow_unknown
=True),
314 "pwdUpdateRequired": JLeaf(bool)
315 }, allow_unknown
=False))
318 # test with Cookies set
319 self
.login("admin", "admin", set_cookies
=True)
320 self
._post
("/api/auth/check", {"token": self
.jsonBody()["token"]}, set_cookies
=True)
321 self
.assertStatus(200)
322 data
= self
.jsonBody()
323 self
.assertSchema(data
, JObj(sub_elems
={
324 "username": JLeaf(str),
325 "permissions": JObj(sub_elems
={}, allow_unknown
=True),
327 "pwdUpdateRequired": JLeaf(bool)
328 }, allow_unknown
=False))
329 self
.logout(set_cookies
=True)
331 def test_check_wo_token(self
):
332 # test with Authorization header
333 self
.login("admin", "admin")
334 self
._post
("/api/auth/check", {"token": ""})
335 self
.assertStatus(200)
336 data
= self
.jsonBody()
337 self
.assertSchema(data
, JObj(sub_elems
={
338 "login_url": JLeaf(str),
339 "cluster_status": JLeaf(str)
340 }, allow_unknown
=False))
343 # test with Cookies set
344 self
.login("admin", "admin", set_cookies
=True)
345 self
._post
("/api/auth/check", {"token": ""}, set_cookies
=True)
346 self
.assertStatus(200)
347 data
= self
.jsonBody()
348 self
.assertSchema(data
, JObj(sub_elems
={
349 "login_url": JLeaf(str),
350 "cluster_status": JLeaf(str)
351 }, allow_unknown
=False))
352 self
.logout(set_cookies
=True)